Compare commits

...

80 Commits

Author SHA1 Message Date
jingshenghao
a90f386ddc feat: Add files generated by qdbusXML2cpp and DCONG2cpp
Add files generated by qdbusXML2cpp and DCONG2cpp

Log: Add files generated by qdbusXML2cpp and DCONG2cpp
2025-01-14 19:32:23 +08:00
deepin-admin-bot
13c4162b5e chore: Sync by 3ab9683b84
sync by github workflow

Log: none
Influence: none
2024-06-19 07:24:54 +00:00
deepin-admin-bot
32140ccf26 chore: Sync by b7b12fd4a9
sync by github workflow

Log: none
Influence: none
2024-06-13 03:00:01 +00:00
Hillwood Yang
697e678587
fix: Need link Xcursor for shutdown plugin (#993)
Log: fix build error on openSUSE
2024-04-17 13:56:34 +08:00
ck
b2da5add21 chore: bump version to 6.0.37
release 6.0.37

Log: bump version to 6.0.37
2024-04-17 09:51:20 +08:00
ck
a15d92c7eb fix: wine app menu obscured by popup widget
remove ToolTip windowflag

Issue: https://github.com/linuxdeepin/developer-center/issues/7612
Bug: https://pms.uniontech.com/bug-view-239173.html
2024-03-28 12:05:23 +08:00
tsic404
00d0f13c1a fix: duplicate tray for some app
some gtk apps use libayatana-appindicator create tray will create xembed and sni duplicate tray
not show sni tray which path contains /org/ayatana/NotificationItem/ created by ayatana-appindicator

log: not show ayatana-appindicator sni tray on xorg
2024-03-26 10:58:44 +08:00
ck
32bd005492 chore: bump version 6.0.36
bump version 6.0.36
2024-03-12 13:10:46 +08:00
ck
3eb95284a0 fix: dcc-dock-plugin icon tweak
控制中心中dock的插件统一混合颜色
暗色主题时填充白色,浅色主题填充黑色

Issue: https://github.com/linuxdeepin/developer-center/issues/6454
2024-03-04 14:52:03 +08:00
ck
1653473ecc fix: bluetooth quick-trays item icon tweak
快捷面板中蓝牙图标和网络插件保持一致
- 大小一致 24x24
- 选中时高亮色填充
- 圆图标

Issue: https://github.com/linuxdeepin/developer-center/issues/7207
2024-02-22 09:34:32 +08:00
zsien
0f940b6579 fix: popup panel cannot be opened when clicking the labels
Issues: linuxdeepin/developer-center#7222
2024-02-02 13:00:44 +08:00
tsic404
72f4286f49 chore: bump version 6.0.35
bump version 6.0.35

log: as title
2024-02-02 10:54:42 +08:00
tsic404
e8e0f3c96f chore: adjust dock ui
1. adjust dock window space to 10
2. make traymainwindow contentsMagins to fixed value
3. make trycontrolpanel background color alpha
4. remove space between fullscreen and dock
5. set border for quick panel items
6. adjust standitem icon and text space
7. adjust sliderContainer icon background color

log: as title
2024-02-02 10:54:42 +08:00
tsic404
48cced00a9 chore: release version 6.0.34
log: as title
2024-01-30 17:34:46 +08:00
tsic404
edea9b860d fix: dock item indicator not update
update dock item position

log: as title
issue: https://github.com/linuxdeepin/developer-center/issues/7097
2024-01-30 08:39:06 +00:00
tsic404
710a9f562b fix: dock plugin unable to click when in keep hide
make dock not hide when click plugin and popup show even in keep hide mode

log: as title
issue: https://github.com/linuxdeepin/developer-center/issues/7132
2024-01-30 16:26:31 +08:00
chenhongtao
478f564631 fix: dock will not auto hide after set size
Issue: https://github.com/linuxdeepin/developer-center/issues/7129
Log:
2024-01-30 08:21:33 +00:00
chenhongtao
241e668ea2 fix: dock animation broken
Issue: https://github.com/linuxdeepin/developer-center/issues/7143
Log:
2024-01-30 16:08:38 +08:00
tsic404
e6e8995e51 fix: dock plugin calculated to an incorrect size
set minSize only for uosai

log: as title
issue: https://github.com/linuxdeepin/developer-center/issues/7127
2024-01-30 08:04:02 +00:00
tsic404
2b81011b7e chore: bump version 6.0.33
bump version 6.0.33

log: as title
2024-01-30 14:07:51 +08:00
tsic404
2bb5e49cac chore: bump version 6.0.32
bump version 6.0.32

log: as title
2024-01-26 14:29:51 +08:00
tsic404
b4ec458dd5 fix: tmp blocked uosai plugin in quickpanel
log: as title
2024-01-26 14:22:12 +08:00
tsic404
572c0c8aad fix: dock theme not follow system
reset dock dapplication palettetype to 0

log: as title
issue: https://github.com/linuxdeepin/developer-center/issues/7090
2024-01-25 08:01:44 +00:00
tsic404
c0c909f9e8 fix: dock get max size when positionChanged and KeepHide mode
no one update hideState properties in taskmanager and
not update dockSize when dock is in hide state by resetDragWindow call

log: as title
issue: https://github.com/linuxdeepin/developer-center/issues/7040
2024-01-25 14:23:18 +08:00
tsic404
8b04a51b51 fix: dock not remove plugin when fcitx exit
rowCountChanged signal not send

log: send rowCountChanged signal
issue: https://github.com/linuxdeepin/developer-center/issues/7080
2024-01-25 14:04:52 +08:00
tsic404
d1f61330f3 chore: release 6.0.31
release 6.0.31

log: as title
2024-01-24 07:28:21 +00:00
tsic404
7097ae7f3c fix: error datetime tooltip
issue: https://github.com/linuxdeepin/developer-center/issues/7056
log: correct longtimeformat and timeformat str
2024-01-23 09:43:02 +00:00
tsic404
3939ca9c12 fix: unable get docked entriy by soft link path
set canonicalFilePath instead of absoluteFilePath for deskfileinfo
and find it by canonicalFilePath instead of user input path

log: use canonicalFilePath instead of absoluteFilePath
2024-01-23 09:43:02 +00:00
chenhongtao
0300e28332 chore: bump version to 6.0.30
Log:
2024-01-23 07:49:39 +00:00
chenhongtao
13b1e661ea chore: update translations
Log:
2024-01-23 06:51:20 +00:00
chenhongtao
b5399bd0ec chore: bring back display setting button
Log:
2024-01-23 06:37:24 +00:00
chenhongtao
945bb03a27 chore: remove Cooperation in display plugin
Issue: linuxdeepin/developer-center#7023
Log:
2024-01-22 09:26:03 +00:00
chenhongtao
0f93647736 chore: bump version to 6.0.29
Log:
2024-01-22 05:48:38 +00:00
chenhongtao
ca4408c660 fix: when dconfig no value, use system format
Log:
2024-01-19 13:37:21 +00:00
tsic404
ee030a6505 chore: release 6.0.28
release 6.0.28

log: as title
2024-01-18 08:20:53 +00:00
Yixue Wang
326f510e4e fix: disable resize of dock popup window
Use setFixedSize instead of resize so that dock popup window is not
resizable.

Log: disable resize of dock popup window
Issue: https://github.com/linuxdeepin/developer-center/issues/6264
2024-01-18 13:09:15 +08:00
tsic404
27e1493982 fix: no one call bamf
try to call bamf

log: as title
2024-01-18 02:00:46 +00:00
wangfei
3a5438b399 fix: the item that removed is exist yet
undock items that removed

Issus: https://github.com/linuxdeepin/developer-center/issues/4631
2024-01-17 09:41:37 +08:00
Yixue Wang
e47a6dfb80 fix: dock wakeup area not changed
When dock is hidden, position change through DBus will not change
frontend rect, thus not update wakeup area. This is because position
in WindowManager is not changed. Emit positionChanged signal in
MultiScreenWorker.

Log: fix dock wakeup area not changed
Issue: https://github.com/linuxdeepin/developer-center/issues/5831
2024-01-16 16:47:11 +08:00
tsic404
b74544aa23 fix: onboard not to show on first click
tray to call show when onboard not launched

log: as title
issue: https://github.com/linuxdeepin/developer-center/issues/6675
2024-01-15 13:32:58 +08:00
Yixue Wang
3b567d096e feat: add dbus property window margin
Add dbus property WindowMargin for other application to calculate
the real exclusiveArea.

Log: add dbus property window margin
2024-01-12 17:56:26 +08:00
dengbo
6b0fec0426 fix: timedate tips show error
timedate tips should bind region format

Log:
2024-01-12 17:24:58 +08:00
chenhongtao
f4a40f36b8 fix: quickpanel icon not follow theme
update quickItem when theme changed

Log:
2024-01-12 06:01:25 +00:00
tsic404
556ea5acf8 chore: release 6.0.27
bump version 6.0.27

log: as title
2024-01-11 17:38:37 +08:00
tsic404
31e149d3d2 fix: dock get stucked when launching
org.ayatana.bamf dbus will get into stucked, so only call it when it's ready

log: only call org.ayatana.bamf when it's ready
issue: https://github.com/linuxdeepin/developer-center/issues/6657
2024-01-10 17:37:06 +08:00
Yixue Wang
a222173da6 fix: item menu may be empty due to error
Parsing item context menu may fail, always check context menu in
mousePressEvent.

Log: fix item menu may be empty due to error
2024-01-10 16:17:20 +08:00
Yixue Wang
01e2377d86 fix: notification tips label and context menu
Add notification settings action. Notification tips label will display
notification count.

Log: fix notification tips label and context menu
2024-01-10 14:01:36 +08:00
ck
263e5a4358 chore: uosai default show on dock (#6486)
Issue: https://github.com/linuxdeepin/developer-center/issues/6486
2024-01-09 17:31:30 +08:00
Yixue Wang
12d346a2c9 fix: cross-thread parenting failure
Cannot create a child in another thread. Do not use object tree, use
QScopedPointer to manage life scope.

Log: fix cross-thread parenting failure
2024-01-09 03:25:28 +00:00
tsic404
bce2a49971 feat: open deepin-calendar instead of dde-widgets when click timedate
call com.deepin.Calendar dbus instead org.deepin.dde.Widgets1

log: as title
2024-01-09 03:17:46 +00:00
Yixue Wang
2a5a1e0efb fix: item context menu not updated
Item context menu is not updated when plugin item request update.

Log: fix item context menu not updated
2024-01-08 16:01:15 +08:00
Yixue Wang
4eecd92395 feat: add plugin notification
Add plugin notification to show notification center. Notification is a
fixed plugin.

Log: add plugin notification
Issue: https://github.com/linuxdeepin/developer-center/issues/6695
2024-01-08 13:41:32 +08:00
Yixue Wang
cf909cd4d7 fix: mainwindow hide when popup opens
MainWindow should not hide when popup opens and the focus is still
on dock even if HideMode is AlwaysHide. Let popup block hiding of
mainwindow.

Log: fix mainwindow hide when popup opens
Issue: https://github.com/linuxdeepin/developer-center/issues/4970
2024-01-04 18:16:11 +08:00
Yixue Wang
107e7427d6 chore: correct indentation
Correct indentation to 4 spaces.

Log: correct indentation
2024-01-04 16:49:51 +08:00
Yixue Wang
79efd518a9 chore: correct typo
Correct typo founded to found.

Log: correct typo
2024-01-04 16:49:51 +08:00
Yixue Wang
6c492486a5 optimize: use invokeMethod instead of singleShot
Use invokeMethod to invoke method in event loop later.

Log: use invokeMethod instead of singleShot
2024-01-04 16:49:51 +08:00
ck
a3499fcf34 chore: bump version to 6.0.26
Relase 6.0.26
2024-01-04 14:29:18 +08:00
ck
e0ac1f9562 chore: update translations
unknown
2024-01-04 14:29:18 +08:00
ck
e02ff1ac53 chore: add fallback media info
如果没有提供默认专辑和歌手信息图标等返回一个默认的图标和文字
如 firefox 播放酷狗音乐只有一个title,其他歌曲信息都没的

Issue: https://github.com/linuxdeepin/developer-center/issues/5786,https://github.com/linuxdeepin/developer-center/issues/4331
2023-12-28 16:38:19 +08:00
ck
d765d60b22 fix: 任务栏媒体播放插件异常
关闭一个播放器后无法再次控制剩余的播放器
记录所有的播放器控制接口,退出一个后回退到上一个播放器控制

Issue: https://github.com/linuxdeepin/developer-center/issues/5719
2023-12-28 16:38:19 +08:00
ck
dab0083dcd fix: item hight error when turn off bluetooth
关闭蓝牙后还会收到上一个操作的设备扫描的新增信号
解决方案是关闭后不再响应这个信号

Issue: https://github.com/linuxdeepin/developer-center/issues/6033
2023-12-28 09:06:11 +08:00
chenhongtao
4e69cb7b68 chore: bump version to 6.0.25
Log:
2023-12-14 07:30:08 +00:00
ck
442a98cb70 fix: turn on bluetooth loading animation not start
change loading animation when bluetooth switch

Issue: https://github.com/linuxdeepin/developer-center/issues/6033
2023-12-12 16:33:37 +08:00
ck
971cd92007 fix: dcc dock plugin icon pixelated again
- 部分图片路径写错
- 资源图片直接加到qicon中,qicon.availableSizes[0]={0, 0}
- 部分插件没有适配主题颜色

Issue: https://github.com/linuxdeepin/developer-center/issues/5682
2023-12-08 16:42:36 +08:00
chenhongtao
c76dcb4361 chore: publish new tag 6.0.24
Log:
2023-11-30 11:43:03 +00:00
chenhongtao
2459613b69 chore: link to dtkgui
Log:
2023-11-28 09:41:08 +00:00
chenhongtao
d2e724b83e Revert "fix: dcc dock plugin icon pixelated"
This reverts commit 58547b091d4a5baea4352d88ff1ad21d8116a980.
2023-11-28 09:41:08 +00:00
chenhongtao
3365365b56 chore: fix use system icon first
Log:
2023-11-23 07:39:51 +00:00
ck
58547b091d fix: dcc dock plugin icon pixelated
use svg format instead of png to support scaling on DPR>1.0

Issue: https://github.com/linuxdeepin/developer-center/issues/5682
2023-11-22 13:06:34 +08:00
chenhongtao
85deffe309 chore: xid is drop in debug, cause coredump
it should use copy

Log:
2023-11-22 03:32:15 +00:00
chenhongtao
919a2b5a49 feat: use system battery icon first
Log:
2023-11-22 03:22:23 +00:00
ck
c2aedfe052 chore: get dconfig value with fallback value
Fallback to default value if dconfig::value failed
if not specify a fallback, default is QVariant()
2023-11-21 14:51:50 +08:00
chenhongtao
70d73662ec chore: when debug open this log
it fursh too much

Log:
2023-11-21 05:30:19 +00:00
chenhongtao
3573bb258b fix: brightness silder cannot scroll when is 28
double 0.29 * 100 then cast to init, it is 28

Log:
Issue: https://github.com/linuxdeepin/developer-center/issues/6077
2023-11-21 03:53:06 +00:00
wangfei
afa0494067 chore: update version to 6.0.23
bump version to 6.0.23

Log: update version to 6.0.23
2023-11-06 09:47:43 +08:00
wangfei
f771da5bdb chore: Adapt time format feature
Adapt time format feature from dcc

Issue: https://github.com/linuxdeepin/developer-center/issues/5902
2023-10-26 11:39:57 +08:00
tsic404
f6019f900d chore: remove unused dbus
log: as title
2023-10-09 16:33:11 +08:00
tsic404
7f148d257a fix: double tray show afeter drag into expandTray and drag back
tray show on dock signal name is quickTrayNameChanged

log: connect right signal name
2023-10-09 16:16:32 +08:00
tsic404
67df42b8a4 fix: tray disappear when drag finished
editor auto close when drag finished, but on one reopen

log: reopen editor when drag finished
2023-10-08 06:14:26 +00:00
tsic404
7cd0cddf44 fix: displayplugin disappear when monitor count changed
changedProps.vale get a empty monitors list, and BrightnessAdjWidget
not update  monitor SliderContainer count

log: fix displayplugin disappear
2023-10-07 05:11:56 +00:00
254 changed files with 14025 additions and 6118 deletions

12
.github/workflows/call-api-check.yml vendored Normal file
View File

@ -0,0 +1,12 @@
name: apiCheck
on:
pull_request_target:
types: [opened, synchronize, reopened]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
api-check:
uses: linuxdeepin/.github/.github/workflows/api-check.yml@master

20
.github/workflows/call-debian-check.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: debianCheck
on:
pull_request_target:
types: [opened, synchronize, reopened]
permissions:
pull-requests: write
contents: read
checks: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
debian-check:
uses: linuxdeepin/.github/.github/workflows/debian-check.yml@master
with:
job_name: "debian-check"

17
.github/workflows/call-static-check.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: staticCheck
on:
pull_request_target:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: read
checks: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
static-check:
uses: linuxdeepin/.github/.github/workflows/static-check.yml@master

View File

@ -63,3 +63,8 @@ License: CC0-1.0
Files: plugins/overlay-warning/org.deepin.dde.dock.overlay.policy
Copyright: UnionTech Software Technology Co., Ltd.
License: LGPL-3.0-or-later
Files: toolGenerate/**/*
Copyright: None
License: CC0-1.0

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16)
if (NOT DEFINED VERSION)
set(VERSION 6.0.22)
set(VERSION 6.0.37)
endif()
project(dde-dock)

View File

@ -174,7 +174,7 @@
"visibility":"public"
},
"Dock_Quick_Plugins": {
"value": ["power", "network", "shutdown", "show-desktop", "multitasking"],
"value": ["power", "network", "shutdown", "show-desktop", "multitasking", "notification", "uosai"],
"serial": 0,
"flags": [],
"name": "Quick Plugins show on dock",

122
debian/changelog vendored
View File

@ -1,3 +1,125 @@
dde-dock (6.0.37) unstable; urgency=medium
* release 6.0.37
* fix linuxdeepin/developer-center#7612
-- Mike Chen <chenke@deepin.org> Wed, 03 Apr 2024 10:22:29 +0800
dde-dock (6.0.36) unstable; urgency=medium
* release 6.0.36
* fix linuxdeepin/developer-center#7222
* fix linuxdeepin/developer-center#7207
* fix linuxdeepin/developer-center#6454
-- Mike Chen <chenke@deepin.org> Wed, 06 Mar 2024 16:50:36 +0800
dde-dock (6.0.35) unstable; urgency=medium
* feat: adjust dock ui
-- tsic404 <liuheng@deepin.org> Thu, 01 Feb 2024 10:58:27 +0800
dde-dock (6.0.34) unstable; urgency=medium
* fix: dock animation broken (https://github.com/linuxdeepin/developer-center/issues/7143)
* fix: dock plugin calculated to an incorrect size (https://github.com/linuxdeepin/developer-center/issues/7127)
* fix: dock will not auto hide after set size (https://github.com/linuxdeepin/developer-center/issues/7129)
* fix: dock plugin unable to click when in keep hide (https://github.com/linuxdeepin/developer-center/issues/7132)
* fix: dock item indicator not update (https://github.com/linuxdeepin/developer-center/issues/7097)
-- tsic404 <liuheng@deepin.org> Tue, 30 Jan 2024 16:17:59 +0800
dde-dock (6.0.33) unstable; urgency=medium
* fix: tmp block uosai in quickpanel
-- tsic404 <liuheng@deepin.org> Fri, 26 Jan 2024 14:38:06 +0800
dde-dock (6.0.32) unstable; urgency=medium
* fix: dock get max size when positionChanged and KeepHide mode (https://github.com/linuxdeepin/developer-center/issues/7040)
* fix: dock not remove plugin when fcitx exit (https://github.com/linuxdeepin/developer-center/issues/7080)
* fix: dock theme not follow system (https://github.com/linuxdeepin/developer-center/issues/7090)
-- tsic404 <liuheng@deepin.org> Thu, 25 Jan 2024 14:30:26 +0800
dde-dock (6.0.31) unstable; urgency=medium
* fix: error datetime tooltip (https://github.com/linuxdeepin/developer-center/issues/7056)
* fix: unable get docked entriy by soft link path (https://github.com/linuxdeepin/developer-center/issues/7033)
-- tsic404 <liuheng@deepin.org> Tue, 23 Jan 2024 17:43:44 +0800
dde-dock (6.0.30) unstable; urgency=medium
* chore: remove Cooperation in display plugin (https://github.com/linuxdeepin/developer-center/issues/7023)
-- chenhongtao <chenhongtao@deepin.org> Mon, 22 Jan 2024 17:27:34 +0800
dde-dock (6.0.29) unstable; urgency=medium
* fix: when no timeformat, tooltip is empty
-- chenhongtao <chenhongtao@deepin.org> Mon, 22 Jan 2024 09:47:21 +0800
dde-dock (6.0.28) unstable; urgency=medium
* fix: the item that removed is exist yet (https://github.com/linuxdeepin/developer-center/issues/4631)
* fix: dock wakeup area not changed (https://github.com/linuxdeepin/developer-center/issues/5831)
* fix: onboard not to show on first click (https://github.com/linuxdeepin/developer-center/issues/6675)
* fix: timedate tips show error (https://github.com/linuxdeepin/developer-center/issues/6674)
* fix: quickpanel icon not follow theme (https://github.com/linuxdeepin/developer-center/issues/6263)
* fix: disable resize of dock popup window (https://github.com/linuxdeepin/developer-center/issues/6264)
* feat: add dbus property window margin
-- tsic404 <liuheng@deepin.org> Thu, 18 Jan 2024 09:57:27 +0800
dde-dock (6.0.27) unstable; urgency=medium
* fix: dock get stucked when launching (https://github.com/linuxdeepin/developer-center/issues/6657)
* chore: make uosai default on dock (https://github.com/linuxdeepin/developer-center/issues/6486)
* chore: open deepin-calendar instead of dde-widgets when click timedate (https://github.com/linuxdeepin/developer-center/issues/6696)
* fix: item context menu not updated
* feat: add plugin notification (https://github.com/linuxdeepin/developer-center/issues/6695)
* fix: mainwindow hide when popup opens (https://github.com/linuxdeepin/developer-center/issues/4970)
-- tsic404 <liuheng@deepin.org> Tue, 09 Jan 2024 13:33:18 +0800
dde-dock (6.0.26) unstable; urgency=medium
* release 6.0.26
* fix #6033 #5719 #5786 #4331
-- mike <chenke@deepin.org> Fri, 29 Dec 2023 11:27:59 +0800
dde-dock (6.0.25) unstable; urgency=medium
* chore: turn on bluetooth loading animation when not start
* fix: fix again set dcc dock plugin icon pixelated
-- chenhongtao <chenhongtao@deepin.org> Wed, 13 Dec 2023 15:31:57 +0800
dde-dock (6.0.24) unstable; urgency=medium
* chore: use system icon first
* fix: dcc dock plugin icon pixelated
* fix some coredump issue
* fix: brightness silder cannot sroll when is 28
* tidy up some log
-- chenhongtao <chenhongtao@deepin.org> Tue, 28 Nov 2023 10:51:52 +0800
dde-dock (6.0.23) unstable; urgency=medium
* fix: displayplugin disappear when monitor count changed
* fix: tray disappear when drag finished
* fix: double tray show afeter drag into expandTray and drag back
* chore: remove unused dbus
* chore: Adapt time format feature(Issue: https://github.com/linuxdeepin/developer-center/issues/5902)
-- Deepin Packages Builder <packages@deepin.org> Thu, 26 Oct 2023 17:25:38 +0800
dde-dock (6.0.22) unstable; urgency=medium
* fix: a space on tray without trash show

79
debian/control vendored
View File

@ -2,73 +2,80 @@ Source: dde-dock
Section: x11
Priority: optional
Maintainer: Deepin Packages Builder <packages@deepin.com>
Build-Depends: debhelper-compat (= 10),
pkg-config,
Build-Depends:
cmake,
qt5-qmake,
libxcb-image0-dev,
libxcb-composite0-dev,
libxcb-ewmh-dev,
libxtst-dev,
qttools5-dev-tools,
qtbase5-private-dev,
libxcb-icccm4-dev,
libqt5x11extras5-dev,
libxcb-damage0-dev,
libqt5svg5-dev,
libdtkwidget-dev (>=5.4.19),
debhelper-compat (= 10),
extra-cmake-modules,
libdbusmenu-qt5-dev,
libdtkcore-dev (>=5.4.14),
libdtkcore5-bin (>=5.4.14),
libdtkgui-dev (>=5.4.13),
libgsettings-qt-dev,
libdbusmenu-qt5-dev,
libgtest-dev,
libgmock-dev,
qttools5-dev,
libxcursor-dev,
libxres-dev,
libqt5waylandclient5-dev,
qtwayland5-private-dev,
libxdamage-dev,
libdtkwidget-dev (>=5.4.19),
libdwayland-dev,
extra-cmake-modules
libgmock-dev,
libgsettings-qt-dev,
libgtest-dev,
libqt5svg5-dev,
libqt5waylandclient5-dev,
libqt5x11extras5-dev,
libxcb-composite0-dev,
libxcb-damage0-dev,
libxcb-ewmh-dev,
libxcb-icccm4-dev,
libxcb-image0-dev,
libxcursor-dev,
libxdamage-dev,
libxres-dev,
libxtst-dev,
pkg-config,
qt5-qmake,
qtbase5-private-dev,
qttools5-dev,
qttools5-dev-tools,
qtwayland5-private-dev,
Standards-Version: 3.9.8
Homepage: http://www.deepin.org/
Package: dde-dock
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends},
deepin-desktop-schemas (>=5.9.14),
dde-qt5xcb-plugin (>=5.0.25),
Depends:
dbus-bin,
dde-daemon (>=5.13.12),
startdde (>=5.8.9),
dde-qt5xcb-plugin (>=5.0.25),
deepin-desktop-schemas (>=5.9.14),
lastore-daemon (>=5.2.9),
qtxdg-dev-tools,
dbus-bin
startdde (>=5.8.9),
${misc:Depends},
${shlibs:Depends},
Recommends:
dde-disk-mount-plugin,
dde-dock-onboard-plugin,
dde-network-dialog,
dock-network-plugin,
dde-network-dialog
Conflicts:
dde-workspace (<< 2.90.5),
dde-dock-applets,
dde-trash-plugin,
dock-hotspot-plugin
dde-workspace (<< 2.90.5),
dock-hotspot-plugin,
Replaces:
dde-dock-applets,
dde-trash-plugin
dde-trash-plugin,
Description: deepin desktop-environment - dock module
Dock module of deepin desktop-environment
Package: dde-dock-dev
Architecture: any
Depends: ${misc:Depends}
Depends:
${misc:Depends},
Description: deepin desktop-environment - dock module development files
Dock module development files of deepin desktop-environment
Package: dde-dock-onboard-plugin
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, onboard
Depends:
onboard,
${misc:Depends},
${shlibs:Depends},
Description: deepin desktop-environment - dock plugin for onboard
Dock plugin for onboard of deepin desktop-environment

View File

@ -9,4 +9,5 @@ usr/lib/dde-dock/plugins/quick-trays
usr/lib/dde-dock/plugins/libmultitasking.so
usr/lib/dde-dock/plugins/libshow-desktop.so
usr/lib/dde-dock/plugins/libkeyboard-layout.so
usr/lib/dde-dock/plugins/libnotification.so
usr/share/dsg/configs/dde-dock/

View File

@ -84,7 +84,7 @@ DockItemManager::DockItemManager(QObject *parent)
}
// 刷新图标
QMetaObject::invokeMethod(this, "refreshItemsIcon", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, &DockItemManager::refreshItemsIcon, Qt::QueuedConnection);
}
DockItemManager *DockItemManager::instance(QObject *parent)

View File

@ -36,9 +36,9 @@ bool QuickSettingController::eventFilter(QObject *watched, QEvent *event)
void QuickSettingController::startLoader()
{
#ifdef QT_DEBUG
AbstractPluginsController::startLoader(new PluginLoader(QString("%1/..%2").arg(qApp->applicationDirPath()).arg("/plugins/loader"), this));
AbstractPluginsController::startLoader(new PluginLoader(QString("%1/..%2").arg(qApp->applicationDirPath()).arg("/plugins/loader"), this));
#else
AbstractPluginsController::startLoader(new PluginLoader("/usr/lib/dde-dock/plugins/loader", this));
AbstractPluginsController::startLoader(new PluginLoader("/usr/lib/dde-dock/plugins/loader", this));
#endif
}

View File

@ -326,7 +326,7 @@ QIcon DBusDockAdaptors::getSettingIcon(PluginsItemInterface *plugin, QSize &pixm
{
auto iconSize = [](const QIcon &icon) {
QList<QSize> iconSizes = icon.availableSizes();
if (iconSizes.size() > 0)
if (iconSizes.size() > 0 && !iconSizes[0].isNull() )
return iconSizes[0];
return defaultIconSize;
@ -335,7 +335,14 @@ QIcon DBusDockAdaptors::getSettingIcon(PluginsItemInterface *plugin, QSize &pixm
QIcon icon = plugin->icon(DockPart::DCCSetting, colorType);
if (!icon.isNull()) {
pixmapSize = iconSize(icon);
return icon;
QColor c = colorType == DGuiApplicationHelper::LightType ? Qt::black :Qt::white;
QPixmap pixmap = icon.pixmap(pixmapSize);
QPainter pa(&pixmap);
pa.setCompositionMode(QPainter::CompositionMode_SourceIn);
pa.fillRect(pixmap.rect(), c);
return pixmap;
}
// 如果插件中没有设置图标,则根据插件的类型,获取其他的图标

View File

@ -1,47 +0,0 @@
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -c DBusMenu -p dbusmenu com.deepin.menu.Menu.xml
*
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "dbusmenu.h"
/*
* Implementation of interface class DBusMenu
*/
DBusMenu::DBusMenu(const QString &path, QObject *parent)
: QDBusAbstractInterface(staticServerPath(), path, staticInterfaceName(), QDBusConnection::sessionBus(), parent)
{
}
DBusMenu::~DBusMenu()
{
}

View File

@ -1,102 +0,0 @@
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -c DBusMenu -p dbusmenu com.deepin.menu.Menu.xml
*
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef DBUSMENU_H_1436158836
#define DBUSMENU_H_1436158836
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface com.deepin.menu.Menu
*/
class DBusMenu: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticServerPath()
{ return "com.deepin.menu"; }
static inline const char *staticInterfaceName()
{ return "com.deepin.menu.Menu"; }
public:
DBusMenu(const QString &path,QObject *parent = 0);
~DBusMenu();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> SetItemActivity(const QString &itemId, bool isActive)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(itemId) << QVariant::fromValue(isActive);
return asyncCallWithArgumentList(QStringLiteral("SetItemActivity"), argumentList);
}
inline QDBusPendingReply<> SetItemChecked(const QString &itemId, bool checked)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(itemId) << QVariant::fromValue(checked);
return asyncCallWithArgumentList(QStringLiteral("SetItemChecked"), argumentList);
}
inline QDBusPendingReply<> SetItemText(const QString &itemId, const QString &text)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(itemId) << QVariant::fromValue(text);
return asyncCallWithArgumentList(QStringLiteral("SetItemText"), argumentList);
}
inline QDBusPendingReply<> ShowMenu(const QString &menuJsonContent)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(menuJsonContent);
return asyncCallWithArgumentList(QStringLiteral("ShowMenu"), argumentList);
}
Q_SIGNALS: // SIGNALS
void ItemInvoked(const QString &itemId, bool checked);
void MenuUnregistered();
};
namespace com {
namespace deepin {
namespace menu {
typedef ::DBusMenu Menu;
}
}
}
#endif

View File

@ -1,47 +0,0 @@
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -c DBusMenuManager -p dbusmenumanager com.deepin.menu.Manager.xml
*
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "dbusmenumanager.h"
/*
* Implementation of interface class DBusMenuManager
*/
DBusMenuManager::DBusMenuManager(QObject *parent)
: QDBusAbstractInterface(staticServerPath(), staticInterfacePath(), staticInterfaceName(), QDBusConnection::sessionBus(), parent)
{
}
DBusMenuManager::~DBusMenuManager()
{
}

View File

@ -1,87 +0,0 @@
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -c DBusMenuManager -p dbusmenumanager com.deepin.menu.Manager.xml
*
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef DBUSMENUMANAGER_H_1436158928
#define DBUSMENUMANAGER_H_1436158928
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface com.deepin.menu.Manager
*/
class DBusMenuManager: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticServerPath()
{ return "com.deepin.menu"; }
static inline const char *staticInterfacePath()
{ return "/com/deepin/menu"; }
static inline const char *staticInterfaceName()
{ return "com.deepin.menu.Manager"; }
public:
explicit DBusMenuManager(QObject *parent = 0);
~DBusMenuManager();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<QDBusObjectPath> RegisterMenu()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("RegisterMenu"), argumentList);
}
inline QDBusPendingReply<> UnregisterMenu(const QString &menuObjectPath)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(menuObjectPath);
return asyncCallWithArgumentList(QStringLiteral("UnregisterMenu"), argumentList);
}
Q_SIGNALS: // SIGNALS
};
namespace com {
namespace deepin {
namespace menu {
typedef ::DBusMenuManager Manager;
}
}
}
#endif

View File

@ -17,6 +17,7 @@ DockDaemonDBusAdaptor::DockDaemonDBusAdaptor(QObject *parent)
connect(TaskManager::instance(), &TaskManager::frontendWindowRectChanged, this, &DockDaemonDBusAdaptor::FrontendWindowRectChanged);
connect(TaskManager::instance(), &TaskManager::showRecentChanged, this, &DockDaemonDBusAdaptor::showRecentChanged);
connect(TaskManager::instance(), &TaskManager::showMultiWindowChanged, this, &DockDaemonDBusAdaptor::ShowMultiWindowChanged);
connect(TaskManager::instance(), &TaskManager::windowMarginChanged, this, &DockDaemonDBusAdaptor::WindowMarginChanged);
connect(DockSettings::instance(), &DockSettings::positionModeChanged, this, &DockDaemonDBusAdaptor::PositionChanged);
connect(DockSettings::instance(), &DockSettings::hideModeChanged, this, &DockDaemonDBusAdaptor::HideModeChanged);
connect(DockSettings::instance(), &DockSettings::displayModeChanged, this, &DockDaemonDBusAdaptor::DisplayModeChanged);
@ -104,6 +105,11 @@ void DockDaemonDBusAdaptor::setWindowSizeFashion(uint value)
}
}
uint DockDaemonDBusAdaptor::windowMargin() const
{
return TaskManager::instance()->windowMargin();
}
QRect DockDaemonDBusAdaptor::frontendWindowRect() const
{
return TaskManager::instance()->getFrontendWindowRect();

View File

@ -100,6 +100,7 @@ class DockDaemonDBusAdaptor: public QDBusAbstractAdaptor
" <property access=\"readwrite\" type=\"u\" name=\"HideTimeout\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"WindowSizeEfficient\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"WindowSizeFashion\"/>\n"
" <property access=\"read\" type=\"u\" name=\"WindowMargin\"/>\n"
" <property access=\"read\" type=\"(iiii)\" name=\"FrontendWindowRect\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"HideMode\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"DisplayMode\"/>\n"
@ -142,6 +143,9 @@ public: // PROPERTIES
uint windowSizeFashion() const;
void setWindowSizeFashion(uint value);
Q_PROPERTY(uint WindowMargin READ windowMargin NOTIFY WindowMarginChanged)
uint windowMargin() const;
Q_PROPERTY(QRect FrontendWindowRect READ frontendWindowRect NOTIFY FrontendWindowRectChanged)
QRect frontendWindowRect() const;
@ -198,6 +202,7 @@ Q_SIGNALS: // SIGNALS
void ShowTimeoutChanged(uint value) const;
void WindowSizeEfficientChanged(uint value) const;
void WindowSizeFashionChanged(uint value) const;
void WindowMarginChanged(uint value) const;
void showRecentChanged(bool) const;
void ShowMultiWindowChanged(bool) const;
};
};

View File

@ -159,6 +159,10 @@ int main(int argc, char *argv[])
DockApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
DockApplication app(argc, argv);
// NOTE: dde-shell load dde-dock plugins and mark loader program DS_APP_ID as dde-dock
// so need reset DGuiApplication pallette to follow system
DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::ColorType::UnknownType);
//崩溃信号
signal(SIGSEGV, sig_crash);
signal(SIGILL, sig_crash);

View File

@ -22,6 +22,13 @@ DBusHandler::DBusHandler(TaskManager *taskmanager, QObject *parent)
, m_xEventMonitor(nullptr)
, m_launcher(new org::deepin::dde::Launcher1(launcherService, launcherPath, QDBusConnection::sessionBus(), this))
{
QDBusInterface *interAM = new QDBusInterface(ApplicationManager1DBusName, "/org/desktopspec/ApplicationManager1", "org.desktopspec.DBus.ObjectManager", QDBusConnection::sessionBus(), this);
if (interAM->isValid()) {
connect(interAM, SIGNAL(InterfacesRemoved(const QDBusObjectPath &, const QStringList &)), this, SIGNAL(appUninstalled(const QDBusObjectPath &, const QStringList &)));
} else {
qWarning() << "The interface of AM is invalid:" << interAM->lastError();
}
connect(m_wmSwitcher, &org::deepin::dde::WMSwitcher1::WMChanged, this, [&](QString name) {m_taskmanager->setWMName(name);});
if (!isWaylandSession()) {
m_xEventMonitor = new org::deepin::dde::XEventMonitor1("org.deepin.dde.XEventMonitor1", "/org/deepin/dde/XEventMonitor1", QDBusConnection::sessionBus(), this);
@ -33,6 +40,16 @@ DBusHandler::DBusHandler(TaskManager *taskmanager, QObject *parent)
m_taskmanager->setDdeLauncherVisible(visible);
m_taskmanager->updateHideState(true);
});
// try to active bamf in another thread
QtConcurrent::run([ = ] {
QDBusInterface bamfInterface(
QStringLiteral("org.ayatana.bamf"),
QStringLiteral("/org/ayatana/bamf/matcher"),
QStringLiteral("org.ayatana.bamf.matcher"),
QDBusConnection::sessionBus()
);
});
}
void DBusHandler::listenWaylandWMSignals()

View File

@ -66,6 +66,9 @@ public:
bool newStartManagerAvaliable();
void sendFailedDockNotification(const QString &appName);
Q_SIGNALS:
void appUninstalled(const QDBusObjectPath &objectPath, const QStringList &interfaces);
private Q_SLOTS:
void handleWlActiveWindowChange();
void onActiveWindowButtonRelease(int type, int x, int y, const QString &key);

View File

@ -40,7 +40,7 @@ DesktopInfo::DesktopInfo(const QString &desktopfile)
}
}
m_desktopFilePath = desktopFileInfo.absoluteFilePath();
m_desktopFilePath = desktopFileInfo.canonicalFilePath();
m_isValid = desktopFileInfo.isAbsolute() && QFile::exists(desktopFileInfo.absoluteFilePath());
m_desktopFile.reset(new QSettings(m_desktopFilePath, QSettings::IniFormat));
m_desktopFile->setIniCodec("utf-8");

View File

@ -162,9 +162,11 @@ QList<Entry*> Entries::getEntries()
Entry *Entries::getDockedEntryByDesktopFile(const QString &desktopFile)
{
QFileInfo desktopFileInfo(desktopFile);
Entry *ret = nullptr;
for (auto entry : filterDockedEntries()) {
if ((entry->isValid()) && desktopFile == entry->getFileName()) {
if ((entry->isValid()) && desktopFileInfo.canonicalFilePath() == entry->getFileName()) {
ret = entry;
break;
}

View File

@ -17,7 +17,6 @@
#include "waylandmanager.h"
#include "windowinfobase.h"
#include "dbusutil.h"
#include "org_deepin_dde_kwayland_plasmawindow.h"
#include <QDir>
@ -27,10 +26,16 @@
#include <QPixmap>
#include <cstdint>
#include <dtkcore_global.h>
#include <functional>
#include <iterator>
#include <memory>
#include <algorithm>
#include <dutil.h>
DCORE_USE_NAMESPACE
#define SETTING DockSettings::instance()
#define XCB XCBUtils::instance()
bool shouldShowEntry(Entry *entry)
@ -50,6 +55,7 @@ TaskManager::TaskManager(QObject *parent)
, m_hideState(HideState::Unknown)
, m_ddeLauncherVisible(false)
, m_trayGridWidgetVisible(false)
, m_popupVisible(false)
, m_entries(new Entries(this))
, m_windowIdentify(new WindowIdentify(this))
, m_dbusHandler(new DBusHandler(this))
@ -90,6 +96,20 @@ TaskManager::TaskManager(QObject *parent)
connect(m_x11Manager, &X11Manager::requestHandleActiveWindowChange, this, &TaskManager::handleActiveWindowChanged);
connect(m_x11Manager, &X11Manager::requestAttachOrDetachWindow, this, &TaskManager::attachOrDetachWindow);
}
connect(m_dbusHandler, &DBusHandler::appUninstalled, this, [this] (const QDBusObjectPath &objectPath, const QStringList &interfaces) {
Q_UNUSED(interfaces)
QString desktopFile = DUtil::unescapeFromObjectPath(objectPath.path());
QString desktopName = desktopFile.split('/').last();
QList<Entry *> entries = m_entries->getEntries();
auto desktopEntryIter = std::find_if(entries.begin(), entries.end(), [desktopName] (Entry *entry) {
return entry->getDesktopFile().contains(desktopName);
});
if (desktopEntryIter != entries.end()) {
undockEntry(*desktopEntryIter);
} else {
qWarning() << "The entry which is to be removed is not found!";
}
});
}
TaskManager::~TaskManager()
@ -248,7 +268,7 @@ bool TaskManager::shouldShowOnDock(WindowInfoBase *info)
*/
void TaskManager::setDdeLauncherVisible(bool visible)
{
m_trayGridWidgetVisible = visible;
m_ddeLauncherVisible = visible;
}
/**
@ -257,7 +277,12 @@ void TaskManager::setDdeLauncherVisible(bool visible)
*/
void TaskManager::setTrayGridWidgetVisible(bool visible)
{
m_ddeLauncherVisible = visible;
m_trayGridWidgetVisible = visible;
}
void TaskManager::setPopupVisible(bool visible)
{
m_popupVisible = visible;
}
/**
@ -365,7 +390,7 @@ void TaskManager::doActiveWindow(XWindow xid)
}
XCB->changeActiveWindow(xid);
QTimer::singleShot(50, [&] {
QTimer::singleShot(50, [xid] {
XCB->restackWindow(xid);
});
}
@ -629,6 +654,9 @@ void TaskManager::initSettings()
connect(SETTING, &DockSettings::showRecentChanged, this, &TaskManager::onShowRecentChanged);
connect(SETTING, &DockSettings::showMultiWindowChanged, this, &TaskManager::onShowMultiWindowChanged);
connect(SETTING, &DockSettings::displayModeChanged, this, &TaskManager::setDisplayMode);
connect(SETTING, &DockSettings::displayModeChanged, this, [this]() {
Q_EMIT windowMarginChanged(windowMargin());
});
}
/**
@ -849,7 +877,7 @@ Entry *TaskManager::getDockedEntryByDesktopFile(const QString &desktopFile)
*/
bool TaskManager::shouldHideOnSmartHideMode()
{
if (!m_activeWindow || m_ddeLauncherVisible || m_trayGridWidgetVisible)
if (!m_activeWindow || m_ddeLauncherVisible || m_trayGridWidgetVisible || m_popupVisible)
return false;
if (!m_isWayland) {
@ -949,7 +977,7 @@ QVector<XWindow> TaskManager::getActiveWinGroup(XWindow xid)
*/
void TaskManager::updateHideState(bool delay)
{
if (m_ddeLauncherVisible || m_trayGridWidgetVisible) {
if (preventDockAutoHide()) {
setPropHideState(HideState::Show);
return;
}
@ -1138,7 +1166,7 @@ void TaskManager::handleActiveWindowChanged(WindowInfoBase *info)
m_activeWindow = info;
XWindow winId = m_activeWindow->getXid();
m_entries->handleActiveWindowChanged(winId);
updateHideState(true);
QTimer::singleShot(200, std::bind(&TaskManager::updateHideState, this, true));
}
/**
@ -1505,6 +1533,11 @@ void TaskManager::setPosition(int position)
SETTING->setPositionMode(Position(position));
}
uint TaskManager::windowMargin() const
{
return SETTING->getDisplayMode() == Dock::Efficient ? 0 : 10;
}
/**
* @brief TaskManager::getShowTimeout
* @return
@ -1572,4 +1605,9 @@ void TaskManager::cancelPreviewWindow()
bool TaskManager::showMultiWindow() const
{
return m_showMultiWindow;
}
}
bool TaskManager::preventDockAutoHide() const
{
return m_ddeLauncherVisible || m_popupVisible || m_trayGridWidgetVisible;
}

View File

@ -41,6 +41,7 @@ public:
bool shouldShowOnDock(WindowInfoBase *info);
void setDdeLauncherVisible(bool visible);
void setTrayGridWidgetVisible(bool visible);
void setPopupVisible(bool visible);
QString getWMName();
void setWMName(QString name);
void setPropHideState(HideState state);
@ -86,6 +87,7 @@ public:
void setIconSize(uint size);
int getPosition();
void setPosition(int position);
uint windowMargin() const;
uint getShowTimeout();
void setShowTimeout(uint timeout);
uint getWindowSizeEfficient();
@ -127,6 +129,7 @@ public:
void previewWindow(uint xid);
void cancelPreviewWindow();
bool preventDockAutoHide() const;
Q_SIGNALS:
void serviceRestarted();
@ -136,6 +139,7 @@ Q_SIGNALS:
void frontendWindowRectChanged(const QRect &dockRect);
void showRecentChanged(bool);
void showMultiWindowChanged(bool);
void windowMarginChanged(uint);
public Q_SLOTS:
void updateHideState(bool delay);
@ -177,6 +181,7 @@ private:
ForceQuitAppMode m_forceQuitAppStatus; // 强制退出应用状态
bool m_ddeLauncherVisible;
bool m_trayGridWidgetVisible;
bool m_popupVisible;
Entries *m_entries; // 所有应用实例
X11Manager *m_x11Manager; // X11窗口管理

View File

@ -13,7 +13,7 @@
#include <QDebug>
#include <QThread>
#include <qstandardpaths.h>
#include <QDBusConnection>
#define XCB XCBUtils::instance()
@ -74,11 +74,28 @@ WindowIdentify::WindowIdentify(TaskManager *_taskmanager, QObject *parent)
m_identifyWindowFuns << qMakePair(QString("FlatpakAppID"), &identifyWindowByFlatpakAppID);
m_identifyWindowFuns << qMakePair(QString("CrxId"), &identifyWindowByCrxId);
m_identifyWindowFuns << qMakePair(QString("Rule"), &identifyWindowByRule);
m_identifyWindowFuns << qMakePair(QString("Bamf"), &identifyWindowByBamf);
m_identifyWindowFuns << qMakePair(QString("Pid"), &identifyWindowByPid);
m_identifyWindowFuns << qMakePair(QString("Scratch"), &identifyWindowByScratch);
m_identifyWindowFuns << qMakePair(QString("GtkAppId"), &identifyWindowByGtkAppId);
m_identifyWindowFuns << qMakePair(QString("WmClass"), &identifyWindowByWmClass);
// should remove bamf identify and turn to new AM
auto *dbusWatcher = new QDBusServiceWatcher(QStringLiteral("org.ayatana.bamf"), QDBusConnection::sessionBus(),
QDBusServiceWatcher::WatchForOwnerChange, this);
auto ifc = QDBusConnection::sessionBus().interface();
if (ifc->isServiceRegistered(QStringLiteral("org.ayatana.bamf"))) {
m_identifyWindowFuns << qMakePair(QString("Bamf"), &identifyWindowByBamf);
}
connect(dbusWatcher, &QDBusServiceWatcher::serviceRegistered, this, [this](){
m_identifyWindowFuns << qMakePair(QString("Bamf"), &identifyWindowByBamf);
});
connect(dbusWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this](){
m_identifyWindowFuns.removeAll(qMakePair(QString("Bamf"), &identifyWindowByBamf));
});
}
AppInfo *WindowIdentify::identifyWindow(WindowInfoBase *winInfo, QString &innerId)

View File

@ -44,13 +44,13 @@ AbstractPluginsController::~AbstractPluginsController()
void AbstractPluginsController::startLoader(PluginLoader *loader)
{
connect(loader, &PluginLoader::finished, loader, &PluginLoader::deleteLater, Qt::QueuedConnection);
connect(loader, &PluginLoader::pluginFounded, this, [ = ](const QString &pluginFile) {
connect(loader, &PluginLoader::pluginFound, this, [ = ](const QString &pluginFile) {
QPair<QString, PluginsItemInterface *> pair;
pair.first = pluginFile;
pair.second = nullptr;
m_pluginLoadMap.insert(pair, false);
});
connect(loader, &PluginLoader::pluginFounded, this, &AbstractPluginsController::loadPlugin, Qt::QueuedConnection);
connect(loader, &PluginLoader::pluginFound, this, &AbstractPluginsController::loadPlugin, Qt::QueuedConnection);
int delay = Utils::SettingValue("com.deepin.dde.dock", "/com/deepin/dde/dock/", "delay-plugins-time", 0).toInt();
QTimer::singleShot(delay, loader, [ = ] { loader->start(QThread::LowestPriority); });
@ -137,9 +137,7 @@ void AbstractPluginsController::loadPlugin(const QString &pluginFile)
// NOTE(justforlxz): 插件的所有初始化工作都在init函数中进行
// loadPlugin函数是按队列执行的initPlugin函数会有可能导致
// 函数执行被阻塞。
QTimer::singleShot(1, this, [ = ] {
initPlugin(interface);
});
QMetaObject::invokeMethod(this, std::bind(&AbstractPluginsController::initPlugin, this, interface), Qt::QueuedConnection);
}
void AbstractPluginsController::initPlugin(PluginsItemInterface *interface)

View File

@ -9,6 +9,7 @@
#include "dbusutil.h"
#include "dockscreen.h"
#include "displaymanager.h"
#include "taskmanager/taskmanager.h"
#include <QScreen>
#include <QApplication>
@ -77,7 +78,7 @@ void DockPopupWindow::setContent(QWidget *content)
m_lastWidget = content;
content->setParent(this);
content->show();
resize(content->sizeHint());
setFixedSize(content->sizeHint());
}
void DockPopupWindow::setExtendWidget(QWidget *widget)
@ -141,7 +142,7 @@ void DockPopupWindow::show(const int x, const int y)
displayPoint.setX(qMin(screenRect.x() + screenRect.width() - getContent()->width(), displayPoint.x()));
}
move(displayPoint);
resize(m_lastWidget->size());
setFixedSize(m_lastWidget->size());
DBlurEffectWidget::show();
activateWindow();
}
@ -172,12 +173,14 @@ void DockPopupWindow::showEvent(QShowEvent *e)
Utils::updateCursor(this);
}
TaskManager::instance()->setPopupVisible(true);
QTimer::singleShot(1, this, &DockPopupWindow::ensureRaised);
}
void DockPopupWindow::hideEvent(QHideEvent *event)
{
m_extendWidget = nullptr;
TaskManager::instance()->setPopupVisible(false);
Dtk::Widget::DBlurEffectWidget::hideEvent(event);
}
@ -249,7 +252,7 @@ void DockPopupWindow::onButtonPress(int type, int x, int y, const QString &key)
// if there is something focus on widget, return
if (auto focus = qApp->focusWidget()) {
auto className = QString(focus->metaObject()->className());
qDebug() << "Find focused widget, focus className is" << className;
//qDebug() << "Find focused widget, focus className is" << className;
if (className == "QLineEdit") {
qDebug() << "PopupWindow window will not be hidden";
return;

View File

@ -46,9 +46,9 @@ void DockSettings::init()
} else if ( key == keyQuickPlugins) {
Q_EMIT quickPluginsChanged(m_dockSettings->value(keyQuickPlugins).toStringList());
} else if ( key == keyWindowSizeFashion) {
Q_EMIT windowSizeFashionChanged(m_dockSettings->value(keyWindowSizeFashion).toUInt());
Q_EMIT windowSizeFashionChanged(m_dockSettings->value(keyWindowSizeFashion, 48).toUInt());
} else if ( key == keyWindowSizeEfficient) {
Q_EMIT windowSizeEfficientChanged(m_dockSettings->value(keyWindowSizeEfficient).toUInt());
Q_EMIT windowSizeEfficientChanged(m_dockSettings->value(keyWindowSizeEfficient, 40).toUInt());
}
});
}
@ -176,7 +176,7 @@ uint DockSettings::getWindowSizeEfficient()
{
uint size = 40;
if (m_dockSettings) {
size = m_dockSettings->value(keyWindowSizeEfficient).toUInt();
size = m_dockSettings->value(keyWindowSizeEfficient, size).toUInt();
}
return size;
}
@ -192,7 +192,7 @@ uint DockSettings::getWindowSizeFashion()
{
uint size = 48;
if (m_dockSettings) {
size = m_dockSettings->value(keyWindowSizeFashion).toUInt();
size = m_dockSettings->value(keyWindowSizeFashion, size).toUInt();
}
return size;
}

View File

@ -4,7 +4,9 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "multiscreenworker.h"
#include "constants.h"
#include "mainwindow.h"
#include "taskmanager/taskmanager.h"
#include "utils.h"
#include "displaymanager.h"
#include "traymainwindow.h"
@ -102,6 +104,10 @@ void MultiScreenWorker::onRegionMonitorChanged(int x, int y, const QString &key)
if (m_registerKey != key || testState(MousePress))
return;
if (m_hideMode == HideMode::KeepHidden) {
TaskManager::instance()->setPropHideState(HideState::Show);
}
tryToShowDock(x, y);
}
@ -122,6 +128,10 @@ void MultiScreenWorker::onExtralRegionMonitorChanged(int x, int y, const QString
// 鼠标移动到任务栏界面之外停止计时器延时2秒改变任务栏所在屏幕
m_delayWakeTimer->stop();
if (m_hideMode == HideMode::KeepHidden && !TaskManager::instance()->preventDockAutoHide()) {
TaskManager::instance()->setPropHideState(HideState::Hide);
}
if (m_hideMode == HideMode::KeepShowing
|| ((m_hideMode == HideMode::KeepHidden || m_hideMode == HideMode::SmartHide) && m_hideState == HideState::Show)) {
Q_EMIT requestPlayAnimation(DOCK_SCREEN->current(), m_position, Dock::AniAction::Show);
@ -132,6 +142,7 @@ void MultiScreenWorker::onExtralRegionMonitorChanged(int x, int y, const QString
void MultiScreenWorker::updateDisplay()
{
tryToHideDock();
//1、屏幕停靠信息
//2、任务栏当前显示在哪个屏幕也需要更新
//3、任务栏高度或宽度调整的拖拽区域
@ -181,6 +192,7 @@ void MultiScreenWorker::onPositionChanged(int position)
qDebug() << "position change from: " << lastPos << " to: " << position;
#endif
m_position = static_cast<Position>(position);
DockItem::setDockPosition(m_position);
if (m_hideMode == HideMode::KeepHidden || (m_hideMode == HideMode::SmartHide && m_hideState == HideState::Hide)) {
// 这种情况切换位置,任务栏不需要显示
@ -192,10 +204,11 @@ void MultiScreenWorker::onPositionChanged(int position)
// 更新当前屏幕信息,下次显示从目标屏幕显示
DOCK_SCREEN->updateDockedScreen(getValidScreen(m_position));
// 需要更新frontendWindowRect接口数据否则会造成HideState属性值不变
emit requestUpdateFrontendGeometry();
Q_EMIT requestUpdateFrontendGeometry();
Q_EMIT positionChanged(m_position);
} else {
// 一直显示的模式才需要显示
emit requestUpdatePosition(lastPos, m_position);
Q_EMIT requestUpdatePosition(lastPos, m_position);
}
}
@ -409,7 +422,7 @@ void MultiScreenWorker::onRequestUpdateRegionMonitor()
}
// 触屏监控高度固定调整为最大任务栏高度100+任务栏与屏幕边缘间距
const int monitHeight = 100 + WINDOWMARGIN;
const int monitHeight = 100 + WINDOWMARGIN * qApp->devicePixelRatio();
// 任务栏触屏唤起区域
m_touchRectList.clear();
@ -537,7 +550,7 @@ void MultiScreenWorker::onRequestDelayShowDock()
void MultiScreenWorker::initMembers()
{
m_monitorUpdateTimer->setInterval(100);
m_monitorUpdateTimer->setInterval(1000);
m_monitorUpdateTimer->setSingleShot(true);
m_delayWakeTimer->setSingleShot(true);
@ -891,7 +904,6 @@ void MultiScreenWorker::onDelayAutoHideChanged()
*/
void MultiScreenWorker::tryToShowDock(int eventX, int eventY)
{
DockItem::setDockPosition(m_position);
if (qApp->property("DRAG_STATE").toBool() || testState(ChangePositionAnimationStart)) {
qWarning() << "dock is draging or animation is running";
return;
@ -946,3 +958,16 @@ void MultiScreenWorker::tryToShowDock(int eventX, int eventY)
}
}
}
void MultiScreenWorker::tryToHideDock()
{
if (hideMode() == HideMode::KeepShowing) {
return;
}
auto mousePos = QCursor::pos();
const QString &currentScreen = DOCK_SCREEN->current();
if (isCursorOut(mousePos.x(), mousePos.y())) {
Q_EMIT requestPlayAnimation(currentScreen, m_position, Dock::AniAction::Hide);
}
}

View File

@ -21,7 +21,7 @@
#include <QObject>
#include <QFlag>
#define WINDOWMARGIN ((m_displayMode == Dock::Efficient) ? 0 : 10)
#define WINDOWMARGIN ((m_displayMode == Dock::Efficient) ? 0 : 5)
#define ANIMATIONTIME 300
#define FREE_POINT(p) if (p) {\
delete p;\
@ -153,6 +153,7 @@ private:
void reInitDisplayData();
void tryToShowDock(int eventX, int eventY);
void tryToHideDock();
void changeDockPosition(QString fromScreen, QString toScreen, const Position &fromPos, const Position &toPos);
void resetDockScreen();

View File

@ -59,7 +59,7 @@ void PluginLoader::run()
}
for (auto plugin : plugins) {
emit pluginFounded(pluginsDir.absoluteFilePath(plugin));
emit pluginFound(pluginsDir.absoluteFilePath(plugin));
}
emit finished();

View File

@ -17,7 +17,7 @@ public:
signals:
void finished() const;
void pluginFounded(const QString &pluginFile) const;
void pluginFound(const QString &pluginFile) const;
protected:
void run();

View File

@ -1,4 +1,4 @@
// Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
// Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
@ -12,6 +12,7 @@
#include <DFontSizeManager>
#include <DDBusSender>
#include <DGuiApplicationHelper>
#include <DConfig>
#include <QHBoxLayout>
#include <QPainter>
@ -31,6 +32,12 @@ static QMap<int, QString> dateFormat{{ 0,"yyyy/M/d" }, { 1,"yyyy-M-d" }, { 2,"yy
{ 4,"yyyy-MM-dd" }, { 5,"yyyy.MM.dd" }, { 6,"yy/M/d" }, { 7,"yy-M-d" }, { 8,"yy.M.d" }};
static QMap<int, QString> timeFormat{{0, "h:mm"}, {1, "hh:mm"}};
const QString localeName_key = "localeName";
const QString shortDateFormat_key = "shortDateFormat";
const QString shortTimeFormat_key = "shortTimeFormat";
const QString longDateFormat_key = "longDateFormat";
const QString longTimeFormat_key = "longTimeFormat";
DateTimeDisplayer::DateTimeDisplayer(bool showMultiRow, QWidget *parent)
: QWidget (parent)
, m_timedateInter(new Timedate("org.deepin.dde.Timedate1", "/org/deepin/dde/Timedate1", QDBusConnection::sessionBus(), this))
@ -43,6 +50,7 @@ DateTimeDisplayer::DateTimeDisplayer(bool showMultiRow, QWidget *parent)
, m_currentSize(0)
, m_oneRow(false)
, m_showMultiRow(showMultiRow)
, m_config(DTK_CORE_NAMESPACE::DConfig::createGeneric("org.deepin.region-format", QString(), this))
{
m_tipPopupWindow.reset(new DockPopupWindow);
// 日期格式变化的时候,需要重绘
@ -63,6 +71,62 @@ DateTimeDisplayer::DateTimeDisplayer(bool showMultiRow, QWidget *parent)
if (Utils::IS_WAYLAND_DISPLAY)
m_tipPopupWindow->setWindowFlags(m_tipPopupWindow->windowFlags() | Qt::FramelessWindowHint);
m_tipPopupWindow->hide();
m_locale = QLocale::system();
initDConfig();
}
void DateTimeDisplayer::initDConfig()
{
QLocale currentLocale = QLocale::system();
if (!m_config->isValid())
return;
if (!m_config->isDefaultValue(localeName_key)) {
m_locale = QLocale(m_config->value(localeName_key).toString());
} else {
m_locale = currentLocale;
}
if (!m_config->isDefaultValue(shortDateFormat_key)) {
m_shortDateFormatStr = m_config->value(shortDateFormat_key).toString();
} else {
m_shortDateFormatStr = currentLocale.dateFormat(QLocale::ShortFormat);
}
if (!m_config->isDefaultValue(shortDateFormat_key)) {
m_longDateFormatStr = m_config->value(longDateFormat_key).toString();
} else {
m_longDateFormatStr = currentLocale.dateFormat(QLocale::LongFormat);
}
if (!m_config->isDefaultValue(shortTimeFormat_key)) {
m_shortTimeFormatStr = m_config->value(shortTimeFormat_key).toString();
} else {
m_shortTimeFormatStr = currentLocale.timeFormat(QLocale::ShortFormat);
}
if (!m_config->isDefaultValue(longTimeFormat_key)) {
m_longTimeFormatStr = m_config->value(longTimeFormat_key).toString();
} else {
m_longTimeFormatStr = currentLocale.timeFormat(QLocale::LongFormat);
}
connect(m_config, &DTK_CORE_NAMESPACE::DConfig::valueChanged, this, [this] (const QString &key) {
if (key == shortDateFormat_key) {
m_shortDateFormatStr = m_config->value(key).toString();
} else if (key == shortTimeFormat_key) {
m_shortTimeFormatStr = m_config->value(key).toString();
} else if (key == localeName_key) {
m_locale = QLocale(m_config->value(key).toString());
} else if (key == longDateFormat_key) {
m_longDateFormatStr = m_config->value(key).toString();
} else if (key == longTimeFormat_key) {
m_longTimeFormatStr = m_config->value(key).toString();
}
update();
});
}
DateTimeDisplayer::~DateTimeDisplayer()
@ -134,10 +198,10 @@ void DateTimeDisplayer::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
DDBusSender().service("org.deepin.dde.Widgets1")
.path("/org/deepin/dde/Widgets1")
.interface("org.deepin.dde.Widgets1")
.method("Toggle").call();
DDBusSender().service("com.deepin.Calendar")
.path("/com/deepin/Calendar")
.interface("com.deepin.Calendar")
.method("RaiseWindow").call();
}
QString DateTimeDisplayer::getTimeString(const Dock::Position &position) const
@ -145,15 +209,10 @@ QString DateTimeDisplayer::getTimeString(const Dock::Position &position) const
QString tFormat = QString("hh:mm");
if (timeFormat.contains(m_shortDateFormat))
tFormat = timeFormat[m_shortDateFormat];
if (!m_shortTimeFormatStr.isEmpty())
tFormat = m_shortTimeFormatStr;
if (!m_use24HourFormat) {
if (position == Dock::Top || position == Dock::Bottom)
tFormat = tFormat.append(" AP");
else
tFormat = tFormat.append("\nAP");
}
return QDateTime::currentDateTime().toString(tFormat);
return m_locale.toString(QDateTime::currentDateTime(), tFormat);
}
QString DateTimeDisplayer::getDateString() const
@ -166,9 +225,12 @@ QString DateTimeDisplayer::getDateString(const Dock::Position &position) const
QString shortDateFormat = "yyyy-MM-dd";
if (dateFormat.contains(m_shortDateFormat))
shortDateFormat = dateFormat.value(m_shortDateFormat);
if (!m_shortDateFormatStr.isEmpty())
shortDateFormat = m_shortDateFormatStr;
// 如果是左右方向,则不显示年份
if (position == Dock::Position::Left || position == Dock::Position::Right) {
static QStringList yearStrList{"yyyy/", "yyyy-", "yyyy.", "yy/", "yy-", "yy."};
static QStringList yearStrList{"yyyy/", "/yyyy", "yyyy-", "-yyyy", "yyyy.", ".yyyy",
"yy/", "/yy", "yy-", "-yy", "yy.", ".yy"};
for (int i = 0; i < yearStrList.size() ; i++) {
const QString &yearStr = yearStrList[i];
if (shortDateFormat.contains(yearStr)) {
@ -178,7 +240,7 @@ QString DateTimeDisplayer::getDateString(const Dock::Position &position) const
}
}
return QDateTime::currentDateTime().toString(shortDateFormat);
return m_locale.toString(QDateTime::currentDateTime(), shortDateFormat);
}
DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo(const Dock::Position &position) const
@ -233,12 +295,7 @@ DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo(const Dock::Posi
void DateTimeDisplayer::onTimeChanged()
{
const QDateTime currentDateTime = QDateTime::currentDateTime();
if (m_use24HourFormat)
m_tipsWidget->setText(QLocale().toString(currentDateTime.date()) + currentDateTime.toString(" HH:mm:ss"));
else
m_tipsWidget->setText(QLocale().toString(currentDateTime.date()) + currentDateTime.toString(" hh:mm:ss AP"));
m_tipsWidget->setText(m_locale.toString(QDate::currentDate(), m_longDateFormatStr) + QString(" ") + m_locale.toString(QTime::currentTime(), m_longTimeFormatStr));
// 如果时间和日期有一个不等,则实时刷新界面
if (m_lastDateString != getDateString() || m_lastTimeString != getTimeString())
@ -248,7 +305,6 @@ void DateTimeDisplayer::onTimeChanged()
void DateTimeDisplayer::onDateTimeFormatChanged()
{
m_shortDateFormat = m_timedateInter->shortDateFormat();
m_use24HourFormat = m_timedateInter->use24HourFormat();
// 此处需要强制重绘因为在重绘过程中才会改变m_currentSize信息方便在后面判断是否需要调整尺寸
repaint();
}
@ -261,7 +317,6 @@ void DateTimeDisplayer::paintEvent(QPaintEvent *e)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
int timeAlignFlag = Qt::AlignCenter;
int dateAlignFlag = Qt::AlignCenter;
@ -344,17 +399,6 @@ void DateTimeDisplayer::updateFont() const
void DateTimeDisplayer::createMenuItem()
{
QAction *timeFormatAction = new QAction(this);
timeFormatAction->setText(m_use24HourFormat ? tr("12-hour time"): tr("24-hour time"));
connect(timeFormatAction, &QAction::triggered, this, [ = ] {
bool use24hourformat = !m_use24HourFormat;
// 此时调用 dbus 更新时间格式但是本地 m_use24HourFormat 未更新,所以需要使用新变量,设置新格式
m_timedateInter->setUse24HourFormat(use24hourformat);
timeFormatAction->setText(use24hourformat ? tr("12-hour time") : tr("24-hour time"));
});
m_menu->addAction(timeFormatAction);
if (!QFile::exists(ICBC_CONF_FILE)) {
QAction *timeSettingAction = new QAction(tr("Time settings"), this);
connect(timeSettingAction, &QAction::triggered, this, [ = ] {

View File

@ -13,10 +13,15 @@
#include <QWidget>
#include <QFont>
#include <dtkcore_global.h>
namespace Dock { class TipsWidget; }
class DockPopupWindow;
class QMenu;
DCORE_BEGIN_NAMESPACE
class DConfig;
DCORE_END_NAMESPACE
using Timedate = org::deepin::dde::Timedate1;
@ -67,6 +72,7 @@ private:
void createMenuItem();
QRect textRect(const QRect &sourceRect) const;
void initDConfig();
private Q_SLOTS:
void onTimeChanged();
@ -87,7 +93,12 @@ private:
bool m_oneRow;
bool m_showMultiRow;
int m_shortDateFormat;
bool m_use24HourFormat;
DTK_CORE_NAMESPACE::DConfig *m_config;
QString m_shortDateFormatStr;
QString m_shortTimeFormatStr;
QString m_longDateFormatStr;
QString m_longTimeFormatStr;
QLocale m_locale;
};
#endif // DATETIMEDISPLAYER_H

View File

@ -1097,7 +1097,7 @@ int MainPanelControl::trayAreaSize(qreal ratio) const
length += (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom ? topWindow->width() * ratio : topWindow->height() * ratio);
}
length += topWindow->dockSpace() * ratio;
length += topWindow->dockSpace();
}
return length;

View File

@ -4,6 +4,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "mainwindowbase.h"
#include "constants.h"
#include "dragwidget.h"
#include "multiscreenworker.h"
#include "dockscreen.h"
@ -270,27 +271,30 @@ void MainWindowBase::resetDragWindow()
if (!screen)
return;
QRect currentRect = getDockGeometry(screen, position(), displayMode(), Dock::HideState::Show);
if (m_multiScreenWorker->hideState() == Dock::HideState::Show) {
QRect currentRect = getDockGeometry(screen, position(), displayMode(), Dock::HideState::Show);
// 这个时候屏幕有可能是隐藏的不能直接使用this->width()这种去设置任务栏的高度,而应该保证原值
int dockSize = 0;
if (m_multiScreenWorker->position() == Position::Left
|| m_multiScreenWorker->position() == Position::Right) {
dockSize = this->width() == 0 ? currentRect.width() : this->width();
} else {
dockSize = this->height() == 0 ? currentRect.height() : this->height();
// 这个时候屏幕有可能是隐藏的不能直接使用this->width()这种去设置任务栏的高度,而应该保证原值
int dockSize = 0;
if (m_multiScreenWorker->position() == Position::Left
|| m_multiScreenWorker->position() == Position::Right) {
dockSize = this->width() == 0 ? currentRect.width() : this->width();
} else {
dockSize = this->height() == 0 ? currentRect.height() : this->height();
}
/** FIX ME
* dockSize的值在40100
* 1dockSize为39dock的mainwindow高度变成9939
* 2dockSize的值在这里不应该为39
*
*/
dockSize = qBound(DOCK_MIN_SIZE, dockSize, DOCK_MAX_SIZE);
// 通知窗管和后端更新数据
m_multiScreenWorker->updateDaemonDockSize(dockSize); // 1.先更新任务栏高度
}
/** FIX ME
* dockSize的值在40100
* 1dockSize为39dock的mainwindow高度变成9939
* 2dockSize的值在这里不应该为39
*
*/
dockSize = qBound(DOCK_MIN_SIZE, dockSize, DOCK_MAX_SIZE);
// 通知窗管和后端更新数据
m_multiScreenWorker->updateDaemonDockSize(dockSize); // 1.先更新任务栏高度
m_multiScreenWorker->requestUpdateFrontendGeometry(); // 2.再更新任务栏位置,保证先1再2
m_multiScreenWorker->requestNotifyWindowManager();
m_multiScreenWorker->requestUpdateRegionMonitor(); // 界面发生变化,应更新监控区域
@ -427,9 +431,9 @@ QRect MainWindowBase::getDockGeometry(QScreen *screen, const Dock::Position &pos
}
int y = 0;
if (pos == Dock::Position::Top)
y = (screenRect.y() + static_cast<int>(margin / ratio));
y = (screenRect.y() + static_cast<int>(margin));
else
y = (screenRect.y() + static_cast<int>(screenRect.height() / ratio - margin / ratio)) - dockSize;
y = (screenRect.y() + static_cast<int>(screenRect.height() / ratio - margin)) - dockSize;
rect.setX(x);
rect.setY(y);
rect.setWidth(width);
@ -447,9 +451,9 @@ QRect MainWindowBase::getDockGeometry(QScreen *screen, const Dock::Position &pos
}
int x = 0;
if (pos == Dock::Position::Left)
x = screenRect.x() + static_cast<int>(margin / ratio);
x = screenRect.x() + static_cast<int>(margin);
else
x = screenRect.x() + static_cast<int>(screenRect.width() /ratio - margin / ratio) - dockSize;
x = screenRect.x() + static_cast<int>(screenRect.width() /ratio - margin) - dockSize;
int y = screenRect.y() + static_cast<int>(((screenRect.height() / ratio) - totalSize) / 2);
// 计算y坐标

View File

@ -23,6 +23,8 @@
#include <QGuiApplication>
#include <QMenu>
#include <QDragLeaveEvent>
#include <algorithm>
#include <QSize>
#define ITEMSIZE 22
#define STARTSPACE 6
@ -434,6 +436,7 @@ void QuickPluginWindow::onUpdatePlugin(PluginsItemInterface *itemInter, const Do
QuickDockItem *quickDockItem = getDockItemByPlugin(itemInter);
if (quickDockItem) {
quickDockItem->updateContextMenu();
updateDockItemSize(quickDockItem);
quickDockItem->update();
}
@ -706,7 +709,12 @@ void QuickDockItem::setPosition(Dock::Position position)
if (m_mainLayout) {
QWidget *itemWidget = m_pluginItem->itemWidget(m_itemKey);
if (itemWidget && m_mainLayout->indexOf(itemWidget) < 0) {
itemWidget->setFixedSize(suitableSize());
auto size= suitableSize();
if (pluginItem()->pluginName() == QStringLiteral("uosai")) {
auto minSize = std::min(size.height(), size.width());
size = QSize(minSize, minSize);
}
itemWidget->setFixedSize(size);
}
}
}
@ -829,29 +837,12 @@ void QuickDockItem::mousePressEvent(QMouseEvent *event)
return QWidget::mousePressEvent(event);
if (m_contextMenu->actions().isEmpty()) {
const QString menuJson = m_pluginItem->itemContextMenu(m_itemKey);
if (menuJson.isEmpty())
return;
QJsonDocument jsonDocument = QJsonDocument::fromJson(menuJson.toLocal8Bit().data());
if (jsonDocument.isNull())
return;
QJsonObject jsonMenu = jsonDocument.object();
QJsonArray jsonMenuItems = jsonMenu.value("items").toArray();
for (auto item : jsonMenuItems) {
QJsonObject itemObj = item.toObject();
QAction *action = new QAction(itemObj.value("itemText").toString());
action->setCheckable(itemObj.value("isCheckable").toBool());
action->setChecked(itemObj.value("checked").toBool());
action->setData(itemObj.value("itemId").toString());
action->setEnabled(itemObj.value("isActive").toBool());
m_contextMenu->addAction(action);
}
updateContextMenu();
}
m_contextMenu->exec(QCursor::pos());
if (!m_contextMenu->actions().isEmpty()) {
m_contextMenu->exec(QCursor::pos());
}
}
void QuickDockItem::enterEvent(QEvent *event)
@ -893,7 +884,13 @@ void QuickDockItem::showEvent(QShowEvent *event)
QWidget *itemWidget = m_pluginItem->itemWidget(m_itemKey);
if (itemWidget && m_mainLayout->indexOf(itemWidget) < 0) {
itemWidget->show();
itemWidget->setFixedSize(suitableSize());
auto size= suitableSize();
if (pluginItem()->pluginName() == QStringLiteral("uosai")) {
auto minSize = std::min(size.height(), size.width());
size = QSize(minSize, minSize);
}
itemWidget->setFixedSize(size);
itemWidget->setFixedSize(size);
m_mainLayout->addWidget(itemWidget);
}
}
@ -1017,6 +1014,31 @@ int QuickDockItem::iconSize() const
return 30;
}
void QuickDockItem::updateContextMenu()
{
m_contextMenu->clear();
const QString menuJson = m_pluginItem->itemContextMenu(m_itemKey);
if (menuJson.isEmpty())
return;
QJsonDocument jsonDocument = QJsonDocument::fromJson(menuJson.toLocal8Bit().data());
if (jsonDocument.isNull())
return;
QJsonObject jsonMenu = jsonDocument.object();
QJsonArray jsonMenuItems = jsonMenu.value("items").toArray();
for (auto item : jsonMenuItems) {
QJsonObject itemObj = item.toObject();
QAction *action = new QAction(itemObj.value("itemText").toString());
action->setCheckable(itemObj.value("isCheckable").toBool());
action->setChecked(itemObj.value("checked").toBool());
action->setData(itemObj.value("itemId").toString());
action->setEnabled(itemObj.value("isActive").toBool());
m_contextMenu->addAction(action);
}
}
QPoint QuickDockItem::topleftPoint() const
{
QPoint p = this->pos();
@ -1068,5 +1090,5 @@ QPoint QuickDockItem::popupMarkPoint() const
void QuickDockItem::onMenuActionClicked(QAction *action)
{
m_pluginItem->invokedMenuItem(m_itemKey, action->data().toString(), true);
m_pluginItem->invokedMenuItem(m_itemKey, action->data().toString(), action->isCheckable() ? action->isChecked() : true);
}

View File

@ -95,6 +95,7 @@ public:
bool canInsert() const;
bool canMove() const;
void hideToolTip();
void updateContextMenu();
QSize suitableSize() const;

View File

@ -19,7 +19,6 @@
#include <QApplication>
#include <QDebug>
#include <QTimer>
#include <qwidget.h>
TrayGridView *TrayGridView::getDockTrayGridView(QWidget *parent)
{
@ -330,7 +329,7 @@ void TrayGridView::dragLeaveEvent(QDragLeaveEvent *e)
{
m_aniStartTime->stop();
e->accept();
dragLeaved();
Q_EMIT dragLeaved();
}
void TrayGridView::dragMoveEvent(QDragMoveEvent *e)
@ -455,6 +454,15 @@ void TrayGridView::handleDropEvent(QDropEvent *e)
e->ignore();
DListView::dropEvent(e);
}
// 拖拽行为后会自动关闭Edtor导致托盘图标消失
QMetaObject::invokeMethod(this, [&] {
for (int i = 0; i < model()->rowCount(); i++) {
QModelIndex index = model()->index(i, 0);
if(!isPersistentEditorOpen(index)) {
openPersistentEditor(index);
}
}
}, Qt::QueuedConnection);
}
void TrayGridView::onUpdateEditorView()
@ -467,7 +475,7 @@ void TrayGridView::onUpdateEditorView()
// 因为closePersistentEditor后异步删除QWidget在关闭后如果立即调用openPersistentEditor在删除的时候会把
// 通过openPersistentEditor新建的QWidget给删除引起bug因此在所有的都closePersistentEditor后异步来调用
// openPersistentEditor就不会出现这种问题
QMetaObject::invokeMethod(this, [ = ] {
QMetaObject::invokeMethod(this, [&] {
for (int i = 0; i < model()->rowCount(); i++) {
QModelIndex index = model()->index(i, 0);
openPersistentEditor(index);

View File

@ -67,7 +67,7 @@ TrayModel::TrayModel(bool isIconTray, QObject *parent)
connect(m_monitor, &TrayMonitor::systemTrayRemoved, this, &TrayModel::onSystemTrayRemoved);
connect(m_monitor, &TrayMonitor::requestUpdateIcon, this, &TrayModel::requestUpdateIcon);
connect(DockSettings::instance(), &DockSettings::quickPluginsChanged, this, &TrayModel::onSettingChanged);
connect(DockSettings::instance(), &DockSettings::quickTrayNameChanged, this, &TrayModel::onSettingChanged);
m_fixedTrayNames = DockSettings::instance()->getTrayItemsOnDock();
m_fixedTrayNames.removeDuplicates();
@ -449,7 +449,7 @@ void TrayModel::removeWinInfo(WinInfo winInfo)
}
}
bool TrayModel::inTrayConfig(const QString itemKey) const
bool TrayModel::inTrayConfig(const QString &itemKey) const
{
if (m_isTrayIcon) {
// 如果是托盘区域,显示所有不在配置中的应用
@ -575,15 +575,13 @@ void TrayModel::onSniTrayRemoved(const QString &servicePath)
// 如果为输入法则无需立刻删除等100毫秒后再观察是否会删除输入法(因为在100毫秒内如果是切换输入法就会很快发送add信号)
if (info.isTypeWriting) {
QTimer::singleShot(100, this, [ servicePath, this ] {
for (WinInfo info : m_winInfos) {
if (info.servicePath == servicePath) {
int index = m_winInfos.indexOf(info);
beginRemoveRows(QModelIndex(), index, index);
m_winInfos.removeOne(info);
endRemoveRows();
}
}
QTimer::singleShot(100, this, [ info, this ] {
int index = m_winInfos.indexOf(info);
beginRemoveRows(QModelIndex(), index, index);
m_winInfos.removeOne(info);
endRemoveRows();
Q_EMIT rowCountChanged();
});
} else {
beginRemoveRows(QModelIndex(), index, index);

View File

@ -141,7 +141,7 @@ private:
QString fileNameByServiceName(const QString &serviceName) const;
bool isTypeWriting(const QString &servicePath) const;
bool inTrayConfig(const QString itemKey) const;
bool inTrayConfig(const QString &itemKey) const;
QString xembedItemKey(quint32 winId) const;
bool xembedCanExport(quint32 winId) const;
QString sniItemKey(const QString &servicePath) const;

View File

@ -6,6 +6,7 @@
#include "tray_monitor.h"
#include "quicksettingcontroller.h"
#include "pluginsiteminterface.h"
#include "utils.h"
TrayMonitor::TrayMonitor(QObject *parent)
: QObject(parent)
@ -110,6 +111,12 @@ void TrayMonitor::onSniItemsChanged()
qWarning() << __FUNCTION__ << "invalid sni service" << s;
continue;
}
if (!Utils::IS_WAYLAND_DISPLAY && s.contains("/org/ayatana/NotificationItem/")) {
qDebug() << "SNI service path created by libayatana-appindicator, duplicate tray with legacy tray";
continue;
}
Q_EMIT sniTrayAdded(s);
}
}

View File

@ -13,7 +13,6 @@
BaseTrayWidget::BaseTrayWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
, m_handleMouseReleaseTimer(new QTimer(this))
, m_ownerPID(0)
, m_needShow(true)
{
m_handleMouseReleaseTimer->setSingleShot(true);
@ -116,11 +115,6 @@ void BaseTrayWidget::resizeEvent(QResizeEvent *event)
}
}
uint BaseTrayWidget::getOwnerPID()
{
return this->m_ownerPID;
}
bool BaseTrayWidget::needShow()
{
return m_needShow;
@ -139,8 +133,3 @@ void BaseTrayWidget::setNeedShow(bool needShow)
update();
}
void BaseTrayWidget::setOwnerPID(uint PID)
{
this->m_ownerPID = PID;
}

View File

@ -28,7 +28,6 @@ public:
virtual void sendClick(uint8_t mouseButton, int x, int y) = 0;
virtual inline TrayType trayType() const { return TrayType::ApplicationTray; } // default is ApplicationTray
virtual bool isValid() {return true;}
uint getOwnerPID();
virtual bool needShow();
virtual void setNeedShow(bool needShow);
virtual QPixmap icon() = 0;
@ -48,14 +47,12 @@ protected:
void handleMouseRelease();
const QRect perfectIconRect() const;
void resizeEvent(QResizeEvent *event) override;
void setOwnerPID(uint PID);
private:
QTimer *m_handleMouseReleaseTimer;
QPair<QPoint, Qt::MouseButton> m_lastMouseReleaseData;
uint m_ownerPID;
bool m_needShow;
};

View File

@ -135,7 +135,7 @@ TrayGridWidget *ExpandIconWidget::popupTrayView()
TrayModel *trayModel = TrayModel::getIconModel();
gridParentView->setTrayGridView(trayView);
gridParentView->setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus);
gridParentView->setWindowFlags(Qt::WindowDoesNotAcceptFocus);
trayView->setModel(trayModel);
trayView->setItemDelegate(trayDelegate);
trayView->setSpacing(ITEM_SPACING);

View File

@ -73,7 +73,6 @@ SNITrayItemWidget::SNITrayItemWidget(const QString &sniServicePath, QWidget *par
m_dbusPath = pair.second;
QDBusConnection conn = QDBusConnection::sessionBus();
setOwnerPID(conn.interface()->servicePid(m_dbusService));
m_sniInter = new StatusNotifierItem(m_dbusService, m_dbusPath, QDBusConnection::sessionBus(), this);
m_sniInter->setSync(false);

View File

@ -76,7 +76,6 @@ XEmbedTrayItemWidget::XEmbedTrayItemWidget(quint32 winId, xcb_connection_t *cnn,
, m_display(disp)
{
wrapWindow();
setOwnerPID(getWindowPID(winId));
m_updateTimer = new QTimer(this);
m_updateTimer->setInterval(100);
@ -521,32 +520,3 @@ bool XEmbedTrayItemWidget::isBadWindow()
return result;
}
uint XEmbedTrayItemWidget::getWindowPID(uint winId)
{
const auto display = IS_WAYLAND_DISPLAY ? XOpenDisplay(nullptr) : QX11Info::display();
if (!display) {
qWarning() << "QX11Info::connection() is " << display;
return 0;
}
Atom nameAtom = XInternAtom(display, "_NET_WM_PID", 1);
Atom type;
int format, status;
unsigned long nitems, after;
unsigned char *data;
unsigned int pid = 0;
status = XGetWindowProperty(display, winId, nameAtom, 0, 1024, 0,
XInternAtom(display, "CARDINAL", 0), &type, &format, &nitems, &after, &data);
if (status == Success && data) {
pid = *((uint*)data);
XFree(data);
}
if (IS_WAYLAND_DISPLAY)
XCloseDisplay(display);
return pid;
}

View File

@ -28,7 +28,6 @@ public:
void sendClick(uint8_t mouseButton, int x, int y) override;
static QString toXEmbedKey(quint32 winId);
static uint getWindowPID(quint32 winId);
static bool isXEmbedKey(const QString &itemKey);
virtual bool isValid() override {return m_valid;}
QPixmap icon() override;

View File

@ -393,9 +393,8 @@ void TrayManagerWindow::resetChildWidgetSize()
int dateTimeHeight = m_appPluginDatetimeWidget->height() - - m.top() - m.bottom() - trayHeight;
m_dateTimeWidget->setFixedSize(dateTimeWidth, dateTimeHeight);
m_systemPluginWidget->setFixedSize(m_systemPluginWidget->suitableSize());
int contentSpace = qMin(MAXDIFF, qMax(((Utils::isDraging() ? height() : (int)m_windowFashionSize) - MINHIGHT), 0)) + MINSPACE;
m_mainLayout->setContentsMargins(contentSpace, contentSpace, contentSpace, contentSpace);
m_mainLayout->setSpacing(contentSpace);
m_mainLayout->setContentsMargins(SINGLEROWSPACE, SINGLEROWSPACE, SINGLEROWSPACE, SINGLEROWSPACE);
m_mainLayout->setSpacing(SINGLEROWSPACE);
// 调整插件和日期窗体的位置显示,这里没有用到布局,是因为在调整任务栏位置的时候,
// 随着布局方向的改变,显示有很大的问题
@ -537,8 +536,8 @@ void TrayManagerWindow::paintEvent(QPaintEvent *event)
painter.save();
painter.setRenderHint(QPainter::Antialiasing);
painter.setClipPath(path);
painter.fillRect(rect().adjusted(1, 1, -1, -1), maskColor(102));
painter.setPen(maskColor(110));
painter.fillRect(rect().adjusted(1, 1, -1, -1), maskColor(255 * 0.1));
painter.setPen(maskColor(255 * 0.15));
painter.drawPath(path);
painter.restore();

View File

@ -816,7 +816,7 @@ void WindowManager::onRequestNotifyWindowManager()
}
XcbMisc::instance()->set_strut_partial(static_cast<xcb_window_t>(mainWindow->winId()), orientation,
static_cast<uint>(strut + WINDOWMARGIN * ratio), // 设置窗口与屏幕边缘距离,需要乘缩放
static_cast<uint>(strut), // 设置窗口与屏幕边缘距离,需要乘缩放
static_cast<uint>(strutStart), // 设置任务栏起点坐标上下为x左右为y
static_cast<uint>(strutEnd)); // 设置任务栏终点坐标上下为x左右为y
}

View File

@ -12,3 +12,4 @@ add_subdirectory("show-desktop")
add_subdirectory("multitasking")
add_subdirectory("bluetooth")
add_subdirectory("airplane-mode")
add_subdirectory("notification")

View File

@ -24,7 +24,7 @@ DWIDGET_USE_NAMESPACE
BluetoothMainWidget::BluetoothMainWidget(AdaptersManager *adapterManager, QWidget *parent)
: QWidget(parent)
, m_adapterManager(adapterManager)
, m_iconWidget(new QWidget(this))
, m_iconButton(new DIconButton(this))
, m_nameLabel(new QLabel(this))
, m_stateLabel(new QLabel(this))
, m_expandLabel(new QLabel(this))
@ -40,63 +40,7 @@ BluetoothMainWidget::~BluetoothMainWidget()
bool BluetoothMainWidget::eventFilter(QObject *watcher, QEvent *event)
{
if (watcher == m_iconWidget) {
switch (event->type()) {
case QEvent::Paint: {
QPainter painter(m_iconWidget);
// 在区域最中间绘制
QRect iconRect = m_iconWidget->rect();
int size = qMin(iconRect.height(), iconRect.width());
QPoint ptCenter(iconRect.center());
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
// 填充原型路径
QPainterPath path;
path.addEllipse(ptCenter, size / 2 - 1, size / 2 - 1);
// 设置黑色背景色
QColor backColor = (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::LightType ? Qt::black : Qt::white);
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::LightType)
backColor.setAlphaF(m_mouseEnter ? 0.2 : 0.1);
else
backColor.setAlphaF(m_mouseEnter ? 0.1 : 0.2);
painter.setBrush(backColor);
painter.fillPath(path, backColor);
// 添加图标
bool blueStatus = isOpen();
QPixmap pixmap(bluetoothIcon(blueStatus));
if (blueStatus) {
QPainter pa(&pixmap);
pa.setCompositionMode(QPainter::CompositionMode_SourceIn);
pa.fillRect(pixmap.rect(), qApp->palette().highlight());
}
painter.drawPixmap(QPoint(ptCenter.x() - pixmap.size().width() / 2, ptCenter.y() - pixmap.size().height() / 2), pixmap);
return true;
}
case QEvent::Enter: {
m_mouseEnter = true;
m_iconWidget->update();
break;
}
case QEvent::Leave: {
m_mouseEnter = false;
m_iconWidget->update();
break;
}
case QEvent::MouseButtonRelease: {
QMouseEvent *mouseevent = static_cast<QMouseEvent *>(event);
if (mouseevent->button() != Qt::LeftButton) {
return QWidget::eventFilter(watcher, event);
}
bool status = !(isOpen());
for (const Adapter *adapter : m_adapterManager->adapters())
m_adapterManager->setAdapterPowered(adapter, status);
return true;
}
default:
break;
}
}
if (watcher == m_expandLabel && event->type() == QEvent::MouseButtonRelease) {
if (watcher != m_iconButton && event->type() == QEvent::MouseButtonRelease) {
Q_EMIT requestExpand();
return true;
}
@ -106,6 +50,9 @@ bool BluetoothMainWidget::eventFilter(QObject *watcher, QEvent *event)
if (watcher == m_stateLabel && event->type() == QEvent::Resize) {
m_stateLabel->setText(QFontMetrics(m_stateLabel->font()).elidedText(m_stateLabel->text(), Qt::TextElideMode::ElideRight, m_stateLabel->width()));
}
if (watcher == m_iconButton && event->type() == QEvent::PaletteChange) {
onPaletteChanged();
}
return QWidget::eventFilter(watcher, event);
}
@ -113,7 +60,15 @@ void BluetoothMainWidget::initUi()
{
QHBoxLayout *mainLayout = new QHBoxLayout(this);
// 添加左侧的图标
m_iconWidget->setFixedWidth(36);
m_iconButton->setEnabledCircle(true);
m_iconButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_iconButton->setFocusPolicy(Qt::FocusPolicy::TabFocus);
m_iconButton->setIconSize({24, 24});
m_iconButton->setIcon(QIcon::fromTheme("bluetooth"));
m_iconButton->setCheckable(true);
m_iconButton->setChecked(isOpen());
onPaletteChanged();
// 添加中间的文本
QWidget *textWidget = new QWidget(this);
QVBoxLayout *textLayout = new QVBoxLayout(textWidget);
@ -146,15 +101,15 @@ void BluetoothMainWidget::initUi()
// 将所有的窗体都添加到主布局中
mainLayout->setContentsMargins(10, 0, 10, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(m_iconWidget);
mainLayout->addWidget(m_iconButton);
mainLayout->addSpacing(10);
mainLayout->addWidget(textWidget);
mainLayout->addStretch();
mainLayout->addWidget(expandWidget);
m_iconWidget->installEventFilter(this);
m_expandLabel->installEventFilter(this);
m_nameLabel->installEventFilter(this);
m_iconButton->installEventFilter(this);
}
void BluetoothMainWidget::initConnection()
@ -168,6 +123,12 @@ void BluetoothMainWidget::initConnection()
for (const Adapter *adapter : m_adapterManager->adapters())
connect(adapter, &Adapter::poweredChanged, this, &BluetoothMainWidget::onAdapterChanged);
connect(m_iconButton, &DIconButton::clicked, this, [this](){
bool status = !(isOpen());
for (const Adapter *adapter : m_adapterManager->adapters())
m_adapterManager->setAdapterPowered(adapter, status);
});
onAdapterChanged();
}
@ -202,5 +163,16 @@ void BluetoothMainWidget::onAdapterChanged()
const QString& text = bluetoothIsOpen ? tr("Turn on") : tr("Turn off");
QFontMetrics fmt{m_stateLabel->font()};
m_stateLabel->setText(fmt.elidedText(text, Qt::TextElideMode::ElideRight,m_stateLabel->width()));
m_iconWidget->update();
m_iconButton->setChecked(bluetoothIsOpen);
}
void BluetoothMainWidget::onPaletteChanged()
{
if (!m_iconButton)
return;
auto pa = m_iconButton->palette();
pa.setColor(QPalette::HighlightedText, pa.color(QPalette::Highlight));
m_iconButton->setPalette(pa);
m_iconButton->update();
}

View File

@ -6,12 +6,16 @@
#ifndef BLUETOOTHMAINWIDGET_H
#define BLUETOOTHMAINWIDGET_H
#include <DIconButton>
#include <QWidget>
class AdaptersManager;
class QLabel;
class Adapter;
DWIDGET_USE_NAMESPACE
class BluetoothMainWidget : public QWidget
{
Q_OBJECT
@ -37,10 +41,11 @@ private:
private Q_SLOTS:
void onAdapterChanged();
void onPaletteChanged();
private:
AdaptersManager *m_adapterManager;
QWidget *m_iconWidget;
DIconButton *m_iconButton;
QLabel *m_nameLabel;
QLabel *m_stateLabel;
QLabel *m_expandLabel;

View File

@ -16,6 +16,7 @@
#include <DListView>
#include <DSpinner>
#include <DGuiApplicationHelper>
#include <DIconTheme>
#include <QBoxLayout>
#include <QStandardItemModel>
@ -115,7 +116,13 @@ QIcon BluetoothDeviceItem::getBatteryIcon(int percentage)
percentageStr = "unknow";
}
return QIcon::fromTheme(QString("battery-%1-symbolic").arg(percentageStr));
QString iconName = QString("battery-%1-symbolic").arg(percentageStr);
auto themeType = DGuiApplicationHelper::instance()->themeType();
bool isDarkTheme = themeType == DGuiApplicationHelper::DarkType;
QString iconNameFallback = isDarkTheme ? iconName + "-dark" : iconName;
QIcon qrcIcon = DIconTheme::findQIcon(iconName, DIconTheme::DontFallbackToQIconFromTheme);
return DIconTheme::findQIcon(iconNameFallback, qrcIcon, DIconTheme::IgnoreBuiltinIcons);
}
@ -230,6 +237,10 @@ void BluetoothAdapterItem::updateIconTheme(DGuiApplicationHelper::ColorType type
QSize BluetoothAdapterItem::sizeHint() const
{
// 没有 item 就不去做一些无效的计算了,包括分割线的高度
if (m_deviceListview->count() < 1)
return QSize(ItemWidth, m_adapterLabel->height());
int visualHeight = 0;
for (int i = 0; i < m_deviceListview->count(); i++)
visualHeight += m_deviceListview->visualRect(m_deviceModel->index(i, 0)).height();
@ -269,6 +280,10 @@ void BluetoothAdapterItem::initData()
void BluetoothAdapterItem::onDeviceAdded(const Device *device)
{
// 关闭蓝牙设备时,不再响应上一个扫描操作的新增的 device
if (!m_adapterStateBtn->isChecked())
return;
int insertRow = 0;
foreach (const auto item, m_deviceItems) {
if (item->device()->connectState()) {
@ -407,6 +422,8 @@ void BluetoothAdapterItem::initConnect()
m_seperator->setVisible(false);
m_adapterStateBtn->setEnabled(false);
m_refreshBtn->setVisible(state);
// FIX #6033 开启蓝牙就开始转动,关闭就停止转动
state ? m_refreshBtn->startRotate() : m_refreshBtn->stopRotate();
emit requestSetAdapterPower(m_adapter, state);
});
connect(m_bluetoothInter, &DBusBluetooth::DisplaySwitchChanged, this, [ = ](bool value) {

View File

@ -46,5 +46,7 @@
<file>light/icons/battery-090-symbolic_20px.svg</file>
<file>light/icons/battery-100-symbolic_20px.svg</file>
<file>light/icons/battery-unknow-symbolic_20px.svg</file>
<file alias="light/texts/bluetooth_16px.svg">light/buletooth_other_light.svg</file>
<file alias="dark/texts/bluetooth_16px.svg">dark/buletooth_other_dark.svg</file>
</qresource>
</RCC>

View File

@ -12,13 +12,14 @@
const int ItemSpacing = 5;
BrightnessAdjWidget::BrightnessAdjWidget(QWidget *parent)
BrightnessAdjWidget::BrightnessAdjWidget(BrightnessModel *model, QWidget *parent)
: QWidget(parent)
, m_mainLayout(new QVBoxLayout(this))
, m_brightnessModel(new BrightnessModel(this))
, m_brightnessModel(model)
{
m_mainLayout->setMargin(0);
m_mainLayout->setSpacing(ItemSpacing);
connect(m_brightnessModel, &BrightnessModel::monitorChanged, this, &BrightnessAdjWidget::loadBrightnessItem);
loadBrightnessItem();
}
@ -28,6 +29,11 @@ void BrightnessAdjWidget::loadBrightnessItem()
QList<BrightMonitor *> monitors = m_brightnessModel->monitors();
int itemHeight = monitors.count() > 1 ? 56 : 30;
// 清理之前的widget
while(m_mainLayout->count() > 0) {
m_mainLayout->takeAt(0)->widget()->deleteLater();
}
for (BrightMonitor *monitor : monitors) {
SliderContainer *sliderContainer = new SliderContainer(this);
if (monitors.count() > 1)
@ -54,5 +60,6 @@ void BrightnessAdjWidget::loadBrightnessItem()
QMargins margins = this->contentsMargins();
setFixedHeight(margins.top() + margins.bottom() + monitors.count() * itemHeight + monitors.count() * ItemSpacing);
Q_EMIT sizeChanged();
}

View File

@ -19,9 +19,12 @@ class BrightnessAdjWidget : public QWidget
{
Q_OBJECT
public:
explicit BrightnessAdjWidget(QWidget *parent = nullptr);
explicit BrightnessAdjWidget(BrightnessModel *model, QWidget *parent = nullptr);
private:
Q_SIGNALS:
void sizeChanged();
private Q_SLOTS:
void loadBrightnessItem();
private:

View File

@ -11,6 +11,7 @@
#include <QDebug>
#include <QApplication>
#include <QScreen>
#include <qobjectdefs.h>
static const QString serviceName("org.deepin.dde.Display1");
static const QString servicePath("/org/deepin/dde/Display1");
@ -88,14 +89,10 @@ void BrightnessModel::onPropertyChanged(const QDBusMessage &msg)
if (defaultMonitor)
Q_EMIT primaryChanged(defaultMonitor);
} else if (changedProps.contains("Monitors")) {
int oldSize = m_monitor.size();
qDeleteAll(m_monitor);
m_monitor = readMonitors(changedProps.value("Monitors").value<QList<QDBusObjectPath>>());
if (oldSize == 1 && m_monitor.size() == 0) {
Q_EMIT screenVisibleChanged(false);
} else if (oldSize == 0 && m_monitor.size() == 1) {
Q_EMIT screenVisibleChanged(true);
}
QDBusInterface dbusInter(serviceName, servicePath, serviceInterface, QDBusConnection::sessionBus());
m_monitor = readMonitors(dbusInter.property("Monitors").value<QList<QDBusObjectPath>>());
Q_EMIT monitorChanged();
}
}
@ -178,7 +175,7 @@ void BrightMonitor::onPropertyChanged(const QDBusMessage &msg)
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
if (changedProps.contains("Brightness")) {
int brightness = static_cast<int>(changedProps.value("Brightness").value<double>() * 100);
int brightness = QVariant(changedProps.value("Brightness").value<double>() * 100).toInt();
if (brightness != m_brightness) {
m_brightness = brightness;
Q_EMIT brightnessChanged(brightness);

View File

@ -26,7 +26,7 @@ public:
Q_SIGNALS:
void primaryChanged(BrightMonitor *);
void screenVisibleChanged(bool);
void monitorChanged();
void monitorLightChanged();
protected Q_SLOTS:

View File

@ -1,267 +0,0 @@
// Copyright (C) 2021 ~ 2022 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "collaborationdevmodel.h"
#include <QIcon>
#include <QTimer>
#include <QDebug>
#include <QDBusArgument>
#include <QDBusInterface>
#include <QDBusPendingCall>
#include <QDBusServiceWatcher>
#include <DGuiApplicationHelper>
DGUI_USE_NAMESPACE
DCORE_USE_NAMESPACE
static const QString CollaborationService = "org.deepin.dde.Cooperation1";
static const QString CollaborationPath = "/org/deepin/dde/Cooperation1";
static const QString CollaborationInterface = "org.deepin.dde.Cooperation1";
static const QString ColPropertiesInterface = "org.freedesktop.DBus.Properties";
CollaborationDevModel::CollaborationDevModel(QObject *parent)
: QObject(parent)
, m_colDbusInter(new QDBusInterface(CollaborationService, CollaborationPath, CollaborationInterface, QDBusConnection::sessionBus(), this))
{
if (m_colDbusInter->isValid()) {
QList<QDBusObjectPath> paths = m_colDbusInter->property("Machines").value<QList<QDBusObjectPath>>();
for (const QDBusObjectPath& path : paths) {
CollaborationDevice *device = new CollaborationDevice(path.path(), this);
if (device->isValid())
m_devices[path.path()] = device;
else
device->deleteLater();
}
} else {
qWarning() << CollaborationService << " is invalid";
}
m_colDbusInter->connection().connect(CollaborationService, CollaborationPath, ColPropertiesInterface,
"PropertiesChanged", "sa{sv}as", this, SLOT(onPropertyChanged(QDBusMessage)));
auto *dbusWatcher = new QDBusServiceWatcher(CollaborationService, m_colDbusInter->connection(),
QDBusServiceWatcher::WatchForUnregistration, this);
connect(dbusWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this](){
qWarning() << CollaborationService << "unregistered";
clear();
});
}
void CollaborationDevModel::checkServiceValid()
{
if (!m_colDbusInter->isValid()) {
clear();
}
}
QList<CollaborationDevice *> CollaborationDevModel::devices() const
{
return m_devices.values();
}
void CollaborationDevModel::onPropertyChanged(const QDBusMessage &msg)
{
QList<QVariant> arguments = msg.arguments();
if (3 != arguments.count())
return;
QString interfaceName = msg.arguments().at(0).toString();
if (interfaceName != CollaborationInterface)
return;
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
if (changedProps.contains("Machines")) {
QList<QDBusObjectPath> paths = m_colDbusInter->property("Machines").value<QList<QDBusObjectPath>>();
QStringList devPaths;
for (const QDBusObjectPath& path : paths) {
devPaths << path.path();
}
updateDevice(devPaths);
}
}
void CollaborationDevModel::updateDevice(const QStringList &devPaths)
{
if (devPaths.isEmpty()) {
qDeleteAll(m_devices);
m_devices.clear();
} else {
// 清除已不存在的设备
QMapIterator<QString, CollaborationDevice *> it(m_devices);
while (it.hasNext()) {
it.next();
if (!devPaths.contains(it.key())) {
it.value()->deleteLater();
m_devices.remove(it.key());
}
}
// 添加新增设备
for (const QString &path : devPaths) {
if (!m_devices.contains(path)) {
CollaborationDevice *device = new CollaborationDevice(path, this);
if (device->isValid())
m_devices[path] = device;
else
device->deleteLater();
}
}
}
emit devicesChanged();
}
void CollaborationDevModel::clear()
{
for (CollaborationDevice *device : m_devices) {
device->deleteLater();
}
m_devices.clear();
Q_EMIT devicesChanged();
}
CollaborationDevice *CollaborationDevModel::getDevice(const QString &machinePath)
{
return m_devices.value(machinePath, nullptr);
}
CollaborationDevice::CollaborationDevice(const QString &devPath, QObject *parent)
: QObject(parent)
, m_path(devPath)
, m_OS(-1)
, m_isConnected(false)
, m_isCooperated(false)
, m_isValid(false)
, m_isCooperating(false)
, m_devDbusInter(new QDBusInterface(CollaborationService, devPath, CollaborationInterface + QString(".Machine"),
QDBusConnection::sessionBus(), this))
{
if (m_devDbusInter->isValid()) {
m_name = m_devDbusInter->property("Name").toString();
m_OS = m_devDbusInter->property("OS").toInt();
m_isConnected = m_devDbusInter->property("Connected").toBool();
m_isCooperated = m_devDbusInter->property("DeviceSharing").toBool();
m_uuid = m_devDbusInter->property("UUID").toString();
m_isValid = true;
} else {
qWarning() << "CollaborationDevice devPath:" << devPath << " is invalid and get properties failed";
}
m_devDbusInter->connection().connect(CollaborationService, m_path, ColPropertiesInterface, "PropertiesChanged",
this, SLOT(onPropertyChanged(QDBusMessage)));
}
bool CollaborationDevice::isValid() const
{
// not show android device
return m_isValid && m_OS != Android;
}
QString CollaborationDevice::name() const
{
return m_name;
}
QString CollaborationDevice::uuid() const
{
return m_uuid;
}
QString CollaborationDevice::machinePath() const
{
return m_path;
}
QString CollaborationDevice::deviceIcon() const
{
switch (m_OS) {
case DeviceType::Android: {
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
return QString(":/ICON_Device_Headphone_dark.svg");
return QString(":/ICON_Device_Headphone.svg");
}
default: {
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
return QString(":/ICON_Device_Laptop_dark.svg");
return QString(":/ICON_Device_Laptop.svg");
}
}
}
bool CollaborationDevice::isConnected() const
{
return m_isConnected;
}
bool CollaborationDevice::isCooperated() const
{
return m_isCooperated;
}
void CollaborationDevice::setDeviceIsCooperating(bool isCooperating)
{
m_isCooperating = isCooperating;
}
void CollaborationDevice::onPropertyChanged(const QDBusMessage &msg)
{
QList<QVariant> arguments = msg.arguments();
if (3 != arguments.count())
return;
QString interfaceName = msg.arguments().at(0).toString();
if (interfaceName != QString("%1.Machine").arg(CollaborationInterface))
return;
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
if (changedProps.contains("Connected")) {
bool isConnected = changedProps.value("Connected").value<bool>();
m_isConnected = isConnected;
if (isConnected && m_isCooperating) {
// paired 成功之后再去请求cooperate
requestCooperate();
}
if (!isConnected){
Q_EMIT pairedStateChanged(false);
}
} else if (changedProps.contains("DeviceSharing")) {
m_isCooperated = changedProps.value("DeviceSharing").value<bool>();
Q_EMIT pairedStateChanged(m_isCooperated);
}
}
void CollaborationDevice::requestCooperate() const
{
callMethod("RequestDeviceSharing");
}
void CollaborationDevice::disconnectDevice() const
{
callMethod("Disconnect");
}
void CollaborationDevice::connect() const
{
callMethod("Connect");
}
QDBusMessage CollaborationDevice::callMethod(const QString &methodName) const
{
if (m_devDbusInter->isValid()) {
QDBusMessage msg = m_devDbusInter->call(methodName);
qInfo() << "CollaborationDevice callMethod:" << methodName << " " << msg.errorMessage();
return msg;
}
qWarning() << "CollaborationDevice callMethod: " << methodName << " failed";
return QDBusMessage();
}

View File

@ -1,108 +0,0 @@
// Copyright (C) 2021 ~ 2022 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#ifndef COLLABORATION_DEV_MODEL_H
#define COLLABORATION_DEV_MODEL_H
#include <QMap>
#include <QObject>
class QTimer;
class QDBusInterface;
class QDBusMessage;
class CollaborationDevice;
/*!
* \brief The CollaborationDevModel class
* model
*/
class CollaborationDevModel : public QObject
{
Q_OBJECT
public:
explicit CollaborationDevModel(QObject *parent = nullptr);
signals:
void devicesChanged();
public:
void checkServiceValid();
QList<CollaborationDevice *> devices() const;
CollaborationDevice *getDevice(const QString &machinePath);
private slots:
void onPropertyChanged(const QDBusMessage &msg);
private:
void updateDevice(const QStringList &devPaths);
void clear();
private:
QDBusInterface *m_colDbusInter;
// machine path : device object
QMap<QString, CollaborationDevice *> m_devices;
};
/*!
* \brief The CollaborationDevice class
*
*/
class CollaborationDevice : public QObject
{
Q_OBJECT
public:
explicit CollaborationDevice(const QString &devPath, QObject *parent = nullptr);
signals:
void pairedStateChanged(bool);
public:
bool isValid() const;
void connect() const;
void requestCooperate() const;
void disconnectDevice() const;
QString name() const;
QString uuid() const;
QString machinePath() const;
QString deviceIcon() const;
bool isConnected() const;
bool isCooperated() const;
void setDeviceIsCooperating(bool isCooperating);
private slots:
void onPropertyChanged(const QDBusMessage &msg);
private:
QDBusMessage callMethod(const QString &methodName) const;
private:
enum DeviceType {
Other = 0,
UOS,
Linux,
Windows,
MacOS,
Android
};
QString m_path;
QString m_name;
QString m_uuid;
int m_OS;
bool m_isConnected;
bool m_isCooperated;
bool m_isValid;
// 标记任务栏点击触发协同连接
bool m_isCooperating;
QDBusInterface *m_devDbusInter;
};
#endif // COLLABORATION_DEV_MODEL_H

View File

@ -1,241 +0,0 @@
// Copyright (C) 2021 ~ 2022 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "devcollaborationwidget.h"
#include "collaborationdevmodel.h"
#include "devitemdelegate.h"
#include <DStyle>
#include <QMap>
#include <QTimer>
#include <QLabel>
#include <QVBoxLayout>
#include <QStandardItemModel>
#define TITLE_HEIGHT 30
#define ITEM_WIDTH 310
#define ITEM_HEIGHT 36
#define LISTVIEW_ITEM_SPACE 5
#define PER_DEGREE 14
DevCollaborationWidget::DevCollaborationWidget(QWidget *parent)
: QWidget(parent)
, m_deviceModel(new CollaborationDevModel(this))
, m_deviceListView(new DListView(this))
, m_viewItemModel(new QStandardItemModel(m_deviceListView))
, m_refreshTimer(new QTimer(this))
{
initUI();
loadDevice();
connect(m_deviceModel, &CollaborationDevModel::devicesChanged, this, &DevCollaborationWidget::loadDevice);
connect(m_deviceListView, &DListView::clicked, this, &DevCollaborationWidget::itemClicked);
connect(m_refreshTimer, &QTimer::timeout, this, &DevCollaborationWidget::refreshViewItem);
}
void DevCollaborationWidget::showEvent(QShowEvent *event)
{
m_deviceModel->checkServiceValid();
QWidget::showEvent(event);
}
void DevCollaborationWidget::resizeEvent(QResizeEvent *event)
{
Q_EMIT sizeChanged();
QWidget::resizeEvent(event);
}
void DevCollaborationWidget::initUI()
{
m_deviceListView->setModel(m_viewItemModel);
QLabel *title = new QLabel(tr("PC collaboration"), this);
title->setFixedHeight(TITLE_HEIGHT);
QHBoxLayout *hLayout = new QHBoxLayout();
hLayout->setContentsMargins(10, 0, 0, 0);
hLayout->addWidget(title);
QVBoxLayout *mainLayout = new QVBoxLayout();
mainLayout->setMargin(0);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
mainLayout->addLayout(hLayout);
mainLayout->addWidget(m_deviceListView);
setLayout(mainLayout);
m_deviceListView->setContentsMargins(0, 0, 0, 0);
m_deviceListView->setFrameShape(QFrame::NoFrame);
m_deviceListView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
m_deviceListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_deviceListView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
m_deviceListView->setResizeMode(QListView::Adjust);
m_deviceListView->setViewportMargins(0, 0, 0, 0);
m_deviceListView->setSpacing(LISTVIEW_ITEM_SPACE);
m_deviceListView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_deviceListView->setItemDelegate(new DevItemDelegate(this));
}
void DevCollaborationWidget::loadDevice()
{
if (!m_deviceListView->count()) {
for (CollaborationDevice *device : m_deviceModel->devices()) {
addItem(device);
}
} else {
updateDeviceListView();
}
if(!m_deviceListView->count()) {
m_deviceListView->hide();
} else {
if (!m_deviceListView->isVisible())
m_deviceListView->setVisible(true);
m_deviceListView->setFixedSize(ITEM_WIDTH, m_deviceListView->count() * ITEM_HEIGHT + LISTVIEW_ITEM_SPACE * (m_deviceListView->count() * 2));
}
resetWidgetSize();
}
void DevCollaborationWidget::addItem(const CollaborationDevice *device)
{
if (!device)
return;
QStandardItem *item = new QStandardItem();
DevItemDelegate::DevItemData data;
data.checkedIconPath = device->deviceIcon(); // TODO
data.text = device->name();
data.iconPath = device->deviceIcon();
int resultState = device->isCooperated() ? DevItemDelegate::Connected : DevItemDelegate::None;
item->setData(QVariant::fromValue(data), DevItemDelegate::StaticDataRole);
item->setData(device->machinePath(), DevItemDelegate::MachinePathDataRole);
item->setData(0, DevItemDelegate::DegreeDataRole);
item->setData(resultState, DevItemDelegate::ResultDataRole);
m_viewItemModel->appendRow(item);
m_deviceItemMap[device->machinePath()] = item;
connect(device, &CollaborationDevice::pairedStateChanged, this, &DevCollaborationWidget::itemStatusChanged);
}
void DevCollaborationWidget::updateDeviceListView()
{
QList<CollaborationDevice *> devices = m_deviceModel->devices();
if (devices.isEmpty()) {
m_deviceListView->removeItems(0, m_deviceListView->count());
m_deviceItemMap.clear();
m_connectingDevices.clear();
return;
}
// 删除不存在设备
for (int row = 0; row < m_deviceListView->count(); row++) {
QStandardItem *item = m_viewItemModel->item(row);
if (!item)
continue;
QString machinePath = item->data(DevItemDelegate::MachinePathDataRole).toString();
if (m_deviceModel->getDevice(machinePath))
continue;
m_deviceListView->removeItem(row);
if (m_deviceItemMap.contains(machinePath)) {
m_deviceItemMap.remove(machinePath);
}
if (m_connectingDevices.contains(machinePath)) {
m_connectingDevices.removeAll(machinePath);
}
}
// 处理新增
for (CollaborationDevice *device : devices) {
if (!m_deviceItemMap.contains(device->machinePath())) {
addItem(device);
}
}
}
void DevCollaborationWidget::resetWidgetSize()
{
int height = TITLE_HEIGHT + (m_deviceListView->count() ? m_deviceListView->height() : 0);
setFixedSize(ITEM_WIDTH, height);
}
void DevCollaborationWidget::itemClicked(const QModelIndex &index)
{
QString machinePath = index.data(DevItemDelegate::MachinePathDataRole).toString();
CollaborationDevice *device = m_deviceModel->getDevice(machinePath);
if (!device)
return;
if (!device->isConnected()) {
device->setDeviceIsCooperating(true);
device->connect();
if (!m_connectingDevices.contains(machinePath))
m_connectingDevices.append(machinePath);
} else if (!device->isCooperated()) {
device->requestCooperate();
if (!m_connectingDevices.contains(machinePath))
m_connectingDevices.append(machinePath);
} else if (device->isCooperated()) {
device->disconnectDevice();
if (m_connectingDevices.contains(machinePath))
m_connectingDevices.removeOne(machinePath);
}
if (!m_connectingDevices.isEmpty() && !m_refreshTimer->isActive())
m_refreshTimer->start(80);
}
void DevCollaborationWidget::itemStatusChanged()
{
CollaborationDevice *device = qobject_cast<CollaborationDevice *>(sender());
if (!device)
return;
device->setDeviceIsCooperating(false);
QString machinePath = device->machinePath();
if (m_deviceItemMap.contains(machinePath) && m_deviceItemMap[machinePath]) {
// 更新item的连接状态
int resultState = device->isCooperated() ? DevItemDelegate::Connected : DevItemDelegate::None;
m_deviceItemMap[machinePath]->setData(resultState, DevItemDelegate::ResultDataRole);
if (device->isCooperated() || !device->isConnected())
m_deviceItemMap[machinePath]->setData(0, DevItemDelegate::DegreeDataRole);
m_deviceListView->update(m_deviceItemMap[machinePath]->index());
if ((resultState == DevItemDelegate::Connected || !device->isConnected()) && m_connectingDevices.contains(machinePath)) {
m_connectingDevices.removeAll(machinePath);
}
}
}
void DevCollaborationWidget::refreshViewItem()
{
if (m_connectingDevices.isEmpty()) {
m_refreshTimer->stop();
return;
}
for (const QString &machinePath : m_connectingDevices) {
if (m_deviceItemMap.contains(machinePath) && m_deviceItemMap[machinePath]) {
int degree = m_deviceItemMap[machinePath]->data(DevItemDelegate::DegreeDataRole).toInt();
degree += PER_DEGREE; // 递进值
m_deviceItemMap[machinePath]->setData(DevItemDelegate::Connecting, DevItemDelegate::ResultDataRole);
m_deviceItemMap[machinePath]->setData(degree, DevItemDelegate::DegreeDataRole);
m_deviceListView->update(m_deviceItemMap[machinePath]->index());
}
}
}

View File

@ -1,57 +0,0 @@
// Copyright (C) 2021 ~ 2022 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#ifndef DEVICE_COLLABORATION_WIDGET_H
#define DEVICE_COLLABORATION_WIDGET_H
#include <QWidget>
#include <DListView>
DWIDGET_USE_NAMESPACE
class CollaborationDevice;
class CollaborationDevModel;
/*!
* \brief The DevCollaborationWidget class
*
*/
class DevCollaborationWidget : public QWidget
{
Q_OBJECT
public:
explicit DevCollaborationWidget(QWidget *parent = nullptr);
signals:
void sizeChanged();
protected:
void showEvent(QShowEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
private slots:
void loadDevice();
void itemClicked(const QModelIndex &index);
void itemStatusChanged();
void refreshViewItem();
private:
void initUI();
void updateDeviceListView();
void addItem(const CollaborationDevice *device);
void resetWidgetSize();
private:
CollaborationDevModel *m_deviceModel;
DListView *m_deviceListView;
QStandardItemModel *m_viewItemModel;
QMap<QString, QStandardItem *> m_deviceItemMap;
QStringList m_connectingDevices;
QTimer *m_refreshTimer;
};
#endif // DEVICE_COLLABORATION_WIDGET_H

View File

@ -1,164 +0,0 @@
// Copyright (C) 2021 ~ 2022 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "devitemdelegate.h"
#include <QtMath>
#include <QPainter>
#include <QPainterPath>
#include <DFontSizeManager>
#define RADIUS_VALUE 10
#define ITEM_SPACE 20
#define ICON_WIDTH 16
#define ICON_HEIGHT 16
#define TEXT_RECT_HEIGHT 20
#define ITEM_HEIGHT 36
#define INDICATOR_SHADOW_OFFSET 10
DevItemDelegate::DevItemDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
void DevItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid())
return;
painter->setRenderHint(QPainter::Antialiasing);
QVariant var = index.data(StaticDataRole);
DevItemData itemData = var.value<DevItemData>();
QRect rect = option.rect;
QPen pen;
pen.setWidth(2);
// 鼠标悬停
if (option.state.testFlag(QStyle::State_MouseOver)) {
pen.setColor(QColor("#EBECED"));
painter->setPen(pen);
painter->setBrush(QColor("#EBECED"));
painter->drawRoundedRect(rect, RADIUS_VALUE, RADIUS_VALUE);
}
// 选中背景(连接上和选中)
int result = index.data(ResultDataRole).toInt();
if (option.state.testFlag(QStyle::State_Selected) && result == Connected) {
pen.setColor(QColor("#0081FF"));
painter->setPen(pen);
painter->setBrush(QColor("#0081FF"));
painter->drawRoundedRect(rect, RADIUS_VALUE, RADIUS_VALUE);
} else {
// 绘制默认背景
pen.setColor(QColor("#EBECED"));
painter->setPen(pen);
painter->setBrush(QColor("#EBECED"));
painter->drawRoundedRect(rect, RADIUS_VALUE, RADIUS_VALUE);
}
bool selected = (option.state.testFlag(QStyle::State_Selected) && result == Connected);
// 绘制Icon
QString imagePath = selected ? itemData.checkedIconPath : itemData.iconPath;
QRect iconRect = QRect(rect.left() + ITEM_SPACE, rect.top() + rect.height() / 2 - ICON_HEIGHT / 2,
ICON_WIDTH, ICON_HEIGHT);
painter->drawImage(iconRect, QImage(imagePath));
// 绘制text
QFont font = Dtk::Widget::DFontSizeManager::instance()->t4();
painter->setFont(font);
pen.setColor(selected ? Qt::white : Qt::black);
painter->setPen(pen);
int textRectWidth = rect.width() - ITEM_SPACE - iconRect.width() - iconRect.width() - ITEM_SPACE;
QRect textRect = QRect(iconRect.right() + ITEM_SPACE, rect.top() + 2,
textRectWidth, rect.height());
QFontMetrics fm(font);
QString itemText = fm.elidedText(itemData.text, Qt::ElideRight, textRectWidth);
painter->drawText(textRect, itemText);
switch (result) {
case ResultState::Connected:
drawResultState(painter, rect);
break;
case ResultState::Connecting:
drawWaitingState(painter, rect, index.data(DegreeDataRole).toInt());
break;
default:
break;
}
}
QSize DevItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index)
return QSize(option.rect.width(), ITEM_HEIGHT);
}
void DevItemDelegate::drawWaitingState(QPainter *painter, const QRect &rect, int degree) const
{
int left = rect.width() - ITEM_SPACE;
int top = rect.top() + rect.height() / 2 - ICON_HEIGHT / 2;
QRect newRect(left, top, ICON_WIDTH, ICON_HEIGHT);
painter->setRenderHint(QPainter::Antialiasing, true);
QList<QList<QColor>> indicatorColors;
for (int i = 0; i < 3; i++)
indicatorColors << createDefaultIndicatorColorList(QColor("#0081FF"));
double radius = 16 * 0.66;
auto center = QRectF(newRect).center();
auto indicatorRadius = radius / 2 / 2 * 1.1;
auto indicatorDegreeDelta = 360 / indicatorColors.count();
for (int i = 0; i < indicatorColors.count(); ++i) {
QList<QColor> colors = indicatorColors.value(i);
for (int j = 0; j < colors.count(); ++j) {
double degreeCurrent = degree - j * INDICATOR_SHADOW_OFFSET + indicatorDegreeDelta * i;
auto x = (radius - indicatorRadius) * qCos(qDegreesToRadians(degreeCurrent));
auto y = (radius - indicatorRadius) * qSin(qDegreesToRadians(degreeCurrent));
x = center.x() + x;
y = center.y() + y;
auto tl = QPointF(x - 1 * indicatorRadius, y - 1 * indicatorRadius);
QRectF rf(tl.x(), tl.y(), indicatorRadius * 2, indicatorRadius * 2);
QPainterPath path;
path.addEllipse(rf);
painter->fillPath(path, colors.value(j));
}
}
}
void DevItemDelegate::drawResultState(QPainter *painter, const QRect &rect) const
{
// 绘制对勾,14x12
int left = rect.width() - ITEM_SPACE;
int top = rect.top() + rect.height() / 2 - 6;
QPainterPath path;
path.moveTo(left, top + 6);
path.lineTo(left + 4, top + 11);
path.lineTo(left + 12, top + 1);
painter->drawPath(path);
}
QList<QColor> DevItemDelegate::createDefaultIndicatorColorList(QColor color) const
{
QList<QColor> colors;
QList<int> opacitys;
opacitys << 100 << 30 << 15 << 10 << 5 << 4 << 3 << 2 << 1;
for (int i = 0; i < opacitys.count(); ++i) {
color.setAlpha(255 * opacitys.value(i) / 100);
colors << color;
}
return colors;
}

View File

@ -1,52 +0,0 @@
// Copyright (C) 2021 ~ 2022 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#ifndef DEVITEMDELEGATE_H
#define DEVITEMDELEGATE_H
#include <DStyledItemDelegate>
/*!
* \brief The DevItemDelegate class
*/
class DevItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
enum DevItemDataRole {
StaticDataRole = Qt::UserRole + 1, // 静态信息
MachinePathDataRole = Qt::UserRole + 2, // machinePath, 可唯一代表一个设备
DegreeDataRole = Qt::UserRole + 3, // degree 绘制waiting使用的参数
ResultDataRole = Qt::UserRole + 4 // 连接结果
};
enum ResultState {
None,
Connecting,
Connected
};
struct DevItemData {
QString checkedIconPath;
QString iconPath;
QString text;
};
public:
explicit DevItemDelegate(QObject *parent = nullptr);
protected:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
private:
void drawWaitingState(QPainter *painter, const QRect &rect, int degree) const;
void drawResultState(QPainter *painter, const QRect &rect) const;
QList<QColor> createDefaultIndicatorColorList(QColor color) const;
};
Q_DECLARE_METATYPE(DevItemDelegate::DevItemData)
#endif // DEVITEMDELEGATE_H

View File

@ -49,7 +49,7 @@ void DisplayPlugin::init(PluginProxyInterface *proxyInter)
m_model.reset(new BrightnessModel);
m_displayWidget.reset(new BrightnessWidget(m_model.data()));
m_displayWidget->setFixedHeight(60);
m_displaySettingWidget.reset(new DisplaySettingWidget);
m_displaySettingWidget.reset(new DisplaySettingWidget(m_model.data()));
if (m_model->monitors().size() > 0)
m_proxyInter->itemAdded(this, pluginName());
@ -60,8 +60,8 @@ void DisplayPlugin::init(PluginProxyInterface *proxyInter)
connect(m_displaySettingWidget.data(), &DisplaySettingWidget::requestHide, this, [ this ] {
m_proxyInter->requestSetAppletVisible(this, QUICK_ITEM_KEY, false);
});
connect(m_model.data(), &BrightnessModel::screenVisibleChanged, this, [ this ](bool visible) {
if (visible)
connect(m_model.data(), &BrightnessModel::monitorChanged, this, [ this ]() {
if (m_model->monitors().size() > 0)
m_proxyInter->itemAdded(this, pluginName());
else
m_proxyInter->itemRemoved(this, pluginName());

View File

@ -4,8 +4,6 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "displaysettingwidget.h"
#include "brightnessadjwidget.h"
#include "devcollaborationwidget.h"
#include <QPushButton>
#include <QVBoxLayout>
@ -14,15 +12,13 @@
const int ItemSpacing = 10;
DisplaySettingWidget::DisplaySettingWidget(QWidget *parent)
DisplaySettingWidget::DisplaySettingWidget(BrightnessModel *model, QWidget *parent)
: QWidget(parent)
, m_brightnessAdjWidget(new BrightnessAdjWidget(this))
, m_collaborationWidget(new DevCollaborationWidget(this))
, m_settingBtn(new QPushButton(tr("Multi-Screen Collaboration"), this))
, m_brightnessAdjWidget(new BrightnessAdjWidget(model, this))
, m_settingBtn(new QPushButton(tr("Display Settings"), this))
{
initUI();
connect(m_settingBtn, &QPushButton::clicked, this, [ this ](){
connect(m_settingBtn, &QPushButton::clicked, this, [ this ](){
DDBusSender().service("org.deepin.dde.ControlCenter1")
.path("/org/deepin/dde/ControlCenter1")
.interface("org.deepin.dde.ControlCenter1")
@ -39,14 +35,13 @@ void DisplaySettingWidget::initUI()
mainLayout->setSpacing(ItemSpacing);
mainLayout->addWidget(m_brightnessAdjWidget);
mainLayout->addWidget(m_collaborationWidget);
mainLayout->addWidget(m_settingBtn);
mainLayout->addStretch();
setLayout(mainLayout);
resizeWidgetHeight();
connect(m_collaborationWidget, &DevCollaborationWidget::sizeChanged,
connect(m_brightnessAdjWidget, &BrightnessAdjWidget::sizeChanged,
this, &DisplaySettingWidget::resizeWidgetHeight);
}
@ -54,5 +49,5 @@ void DisplaySettingWidget::resizeWidgetHeight()
{
QMargins margins = this->contentsMargins();
setFixedHeight(margins.top() + margins.bottom() + m_brightnessAdjWidget->height() +
m_collaborationWidget->height() + m_settingBtn->height() + ItemSpacing * 2);
m_settingBtn->height() + ItemSpacing);
}

View File

@ -6,11 +6,12 @@
#ifndef DISPLAY_SETTING_WIDGET_H
#define DISPLAY_SETTING_WIDGET_H
#include "brightnessadjwidget.h"
#include <QWidget>
class QPushButton;
class BrightnessAdjWidget;
class DevCollaborationWidget;
/*!
* \brief The DisplaySettingWidget class
@ -21,7 +22,7 @@ class DisplaySettingWidget : public QWidget
Q_OBJECT
public:
explicit DisplaySettingWidget(QWidget *parent = nullptr);
explicit DisplaySettingWidget(BrightnessModel *model, QWidget *parent = nullptr);
Q_SIGNALS:
void requestHide();
@ -32,7 +33,6 @@ private:
private:
BrightnessAdjWidget *m_brightnessAdjWidget; // 亮度调整
DevCollaborationWidget *m_collaborationWidget; // 跨端协同
QPushButton *m_settingBtn; // 设置按钮
};

View File

@ -13,6 +13,8 @@
#include <QJsonObject>
#include <QMetaMethod>
#include <QDBusAbstractInterface>
#include <QMetaObject>
#include <QUrl>
MediaPlayerModel::MediaPlayerModel(QObject *parent)
: QObject(parent)
@ -56,42 +58,22 @@ MediaPlayerModel::PlayStatus MediaPlayerModel::status()
const QString MediaPlayerModel::name()
{
if (m_mediaInter) {
Dict data = m_mediaInter->metadata();
return data["xesam:title"].toString();
}
return QString();
return m_name;
}
const QString MediaPlayerModel::iconUrl()
{
if (m_mediaInter) {
Dict data = m_mediaInter->metadata();
return data["mpris:artUrl"].toString();
}
return QString();
return m_icon;
}
const QString MediaPlayerModel::album()
{
if (m_mediaInter) {
Dict data = m_mediaInter->metadata();
return data["xesam:album"].toString();
}
return QString();
return m_album;
}
const QString MediaPlayerModel::artist()
{
if (m_mediaInter) {
Dict data = m_mediaInter->metadata();
return data["xesam:artist"].toString();
}
return QString();
return m_artist;
}
void MediaPlayerModel::setStatus(const MediaPlayerModel::PlayStatus &stat)
@ -122,87 +104,149 @@ void MediaPlayerModel::playNext()
m_mediaInter->Next();
}
void MediaPlayerModel::updateMetadata()
{
if (!m_mediaInter)
return;
Dict v = m_mediaInter->metadata();
m_name = v.value("xesam:title").toString();
m_icon = v.value("mpris:artUrl").toString();
m_album = v.value("xesam:album").toString();
m_artist = v.value("xesam:artist").toString();
auto getName = [&v](const QString &service){
if (service.contains("vlc", Qt::CaseInsensitive)) {
const QString &url = v.value("xesam:url").toString();
if (!url.isEmpty())
return QUrl(url).fileName();
}
return tr("Unknown");
};
auto getIcon = [](const QString &service){
QMap<QString, QString> serv2Icon = {
{"vlc", "vlc"},
{"chromium", "chrome"},
{"firefox", "firefox"},
{"movie", "video"},
{"music", "music"}
};
for(auto k : serv2Icon.keys())
if (service.contains(k, Qt::CaseInsensitive))
return serv2Icon.value(k);
return QString("music");
};
const QString &service = m_mediaInter->service();
if (m_name.isEmpty())
m_name = getName(service);
if (m_icon.isEmpty())
m_icon = getIcon(service);
if (m_album.isEmpty())
m_album = tr("Unknown");
if (m_artist.isEmpty())
m_artist = tr("Unknown");
Q_EMIT MediaPlayerModel::metadataChanged();
}
void MediaPlayerModel::onServiceDiscovered(const QString &service)
{
auto mediaInter = new MediaPlayerInterface(service, "/org/mpris/MediaPlayer2",
QDBusConnection::sessionBus(), this);
// 影院不太希望被控制。。canShowInUI:false
if (!mediaInter->canControl() || !mediaInter->canShowInUI()) {
delete mediaInter;
return;
}
if (!m_mprisServices.contains(service))
m_mprisServices << service;
m_isActived = !m_mprisServices.isEmpty();
if (m_mediaInter && m_mediaInter->service() == service) {
Q_EMIT startStop(m_isActived);
delete mediaInter;
return;
}
if (m_mediaInter)
delete m_mediaInter;
m_mediaInter = mediaInter;
updateMetadata();
connect(m_mediaInter, &MediaPlayerInterface::PlaybackStatusChanged, this, [ this ] {
Q_EMIT statusChanged(convertStatus(m_mediaInter->playbackStatus()));
});
connect(m_mediaInter, &MediaPlayerInterface::MetadataChanged, this, &MediaPlayerModel::updateMetadata);
Q_EMIT startStop(m_isActived);
}
void MediaPlayerModel::onServiceDisappears(const QString &service)
{
if (!m_mprisServices.contains(service))
return;
m_mprisServices.removeAll(service);
m_isActived = !m_mprisServices.isEmpty();
if (m_mediaInter && m_mediaInter->service() == service) {
delete m_mediaInter;
m_mediaInter = nullptr;
}
// 退出当前播放器后,继续控制上一个播放器
if (m_isActived)
return onServiceDiscovered(m_mprisServices.last());
Q_EMIT startStop(m_isActived);
}
void MediaPlayerModel::initMediaPlayer()
{
QDBusInterface dbusInter("org.freedesktop.DBus", "/", "org.freedesktop.DBus", QDBusConnection::sessionBus(), this);
QDBusPendingCall call = dbusInter.asyncCall("ListNames");
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
connect(watcher, &QDBusPendingCallWatcher::finished, [ = ] {
m_serviceName.clear();
m_mprisServices.clear();
if (call.isError())
return;
QDBusReply<QStringList> reply = call.reply();
const QStringList &serviceList = reply.value();
for (const QString &serv : serviceList) {
if (!serv.startsWith("org.mpris.MediaPlayer2"))
continue;
QDBusInterface serviceInterface(serv, "/org/mpris/MediaPlayer2",
"org.mpris.MediaPlayer2.Player", QDBusConnection::sessionBus(), this);
// 如果开启了谷歌浏览器的后台服务(org.mpris.MediaPlayer2.chromium.instance17352)
// 也符合名称要求,但是它不是音乐服务,此时需要判断是否存在这个属性
QVariant v = serviceInterface.property("CanPlay");
if (!v.isValid() || !v.value<bool>())
continue;
m_serviceName = serv;
break;
}
if (!m_serviceName.isEmpty()) {
m_isActived = true;
m_mediaInter = new MediaPlayerInterface(m_serviceName, "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus(), this);
connect(m_mediaInter, &MediaPlayerInterface::PlaybackStatusChanged, this, [ this ] {
Q_EMIT statusChanged(convertStatus(m_mediaInter->playbackStatus()));
});
connect(m_mediaInter, &MediaPlayerInterface::MetadataChanged, this, &MediaPlayerModel::metadataChanged);
Dict v = m_mediaInter->metadata();
m_name = v.value("xesam:title").toString();
m_icon = v.value("mpris:artUrl").toString();
m_album = v.value("xesam:album").toString();
m_artist = v.value("xesam:artist").toString();
Q_EMIT startStop(m_isActived);
return;
onServiceDiscovered(serv);
// break;
}
QDBusConnectionInterface *dbusInterface = QDBusConnection::sessionBus().interface();
connect(dbusInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
[ = ](const QString &name, const QString &, const QString &newOwner) {
if (name.startsWith("org.mpris.MediaPlayer2")) {
// 启动了音乐播放
m_isActived = !newOwner.isEmpty();
if (m_isActived) {
m_serviceName = name;
m_mediaInter = new MediaPlayerInterface(m_serviceName, "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus(), this);
connect(m_mediaInter, &MediaPlayerInterface::PlaybackStatusChanged, this, [ this ] {
Q_EMIT statusChanged(convertStatus(m_mediaInter->playbackStatus()));
});
connect(m_mediaInter, &MediaPlayerInterface::MetadataChanged, this, &MediaPlayerModel::metadataChanged);
Dict v = m_mediaInter->metadata();
m_name = v.value("xesam:title").toString();
m_icon = v.value("mpris:artUrl").toString();
m_album = v.value("xesam:album").toString();
m_artist = v.value("xesam:artist").toString();
} else {
if (!m_serviceName.isEmpty()) {
delete m_mediaInter;
m_mediaInter = nullptr;
}
m_serviceName.clear();
}
Q_EMIT startStop(m_isActived);
if (!name.startsWith("org.mpris.MediaPlayer2"))
return;
if (newOwner.isEmpty()) {
onServiceDisappears(name);
} else {
onServiceDiscovered(name);
}
});
connect(dbusInterface, &QDBusConnectionInterface::serviceUnregistered, this,
[ = ](const QString &service) {
if (service.startsWith("org.mpris.MediaPlayer2")) {
// 启动了音乐播放
m_serviceName.clear();
m_isActived = false;
Q_EMIT startStop(m_isActived);
onServiceDiscovered(service);
}
});
});
@ -248,8 +292,13 @@ void MediaPlayerInterface::onPropertyChanged(const QDBusMessage &msg)
const QMetaObject* self = metaObject();
for (int i = self->propertyOffset(); i < self->propertyCount(); ++i) {
QMetaProperty p = self->property(i);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QGenericArgument value(QMetaType::typeName(p.type()), const_cast<void*>(changedProps[prop].constData()));
#else
QGenericArgument value{p.metaType().name(), const_cast<void*>(changedProps[prop].constData())};
#endif
if (p.name() == prop) {
Q_EMIT p.notifySignal().invoke(this);
Q_EMIT p.notifySignal().invoke(this, value);
}
}
}

View File

@ -54,10 +54,13 @@ Q_SIGNALS:
private:
void initMediaPlayer();
PlayStatus convertStatus(const QString &stat);
void onServiceDiscovered(const QString &service);
void onServiceDisappears(const QString &service);
void updateMetadata();
private:
bool m_isActived;
QString m_serviceName;
QStringList m_mprisServices;
QString m_name;
QString m_icon;
QString m_album;
@ -98,6 +101,18 @@ public:
inline Dict metadata() const
{ return qvariant_cast<Dict>(property("Metadata")); }
Q_PROPERTY(bool CanControl READ canControl NOTIFY CanControlChanged)
inline bool canControl() const
{ return qvariant_cast< bool >(property("CanControl")); }
// from dtkwidget dbusmpris.h
Q_PROPERTY(bool CanShowInUI READ canShowInUI NOTIFY CanShowInUIChanged)
inline bool canShowInUI() const
{
QVariant showInUI = property("CanShowInUI");
// 属性有效且为假表示不能控制 无效或为真表示可以控制
return showInUI.isValid() ? showInUI.toBool() : true;
}
Q_PROPERTY(bool CanGoNext READ canGoNext NOTIFY CanGoNextChanged)
inline bool canGoNext() const
{ return qvariant_cast< bool >(property("CanGoNext")); }
@ -116,6 +131,8 @@ public:
Q_SIGNALS:
void MetadataChanged();
void CanControlChanged(bool value);
void CanShowInUIChanged(bool value);
void CanGoNextChanged();
void CanGoPreviousChanged();
void CanPauseChanged();

View File

@ -115,9 +115,18 @@ void MediaWidget::onUpdateMediaInfo()
{
m_musicName->setText(m_model->name());
QString file = m_model->iconUrl();
if (file.startsWith("file:///"))
QPixmap pixmap;
if (file.startsWith("file:///")) {
file.replace("file:///", "/");
m_musicIcon->setPixmap(QPixmap(file).scaled(m_musicIcon->size()));
pixmap = QPixmap(file).scaled(m_musicIcon->size());
}
if (pixmap.isNull()) {
// 就算给的文件不存在(e.g. deepin-music..),也至少 fallback 到 music 图标
pixmap = QIcon::fromTheme(file, QIcon::fromTheme("music")).pixmap(m_musicIcon->size());
}
m_musicIcon->setPixmap(pixmap);
m_musicSinger->setText(m_model->artist());
}

View File

@ -8,6 +8,7 @@
#include <DWindowManagerHelper>
#include <DDBusSender>
#include <QPainter>
#include <QIcon>
@ -141,8 +142,11 @@ void MultitaskingPlugin::invokedMenuItem(const QString &itemKey, const QString &
QIcon MultitaskingPlugin::icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType)
{
if (dockPart == DockPart::DCCSetting)
return QIcon::fromTheme("dcc-multitasking-view",QIcon(":/icons/icons/dcc-multitasking-view.svg"));
if (dockPart == DockPart::DCCSetting) {
auto icon = QIcon::fromTheme("dcc-multitasking-view", QIcon(":/icons/dcc-multitasking-view.svg"));
QPixmap pixmap = icon.pixmap(QSize(18, 18));
return pixmap;
}
return QIcon();
}
@ -176,4 +180,4 @@ PluginsItemInterface::PluginType MultitaskingPlugin::type()
PluginFlags MultitaskingPlugin::flags() const
{
return PluginFlag::Type_Fixed | Attribute_CanSetting;
}
}

View File

@ -0,0 +1,28 @@
set(PLUGIN_NAME "notification")
find_package(Qt5 REQUIRED COMPONENTS DBus)
find_package(Dtk REQUIRED COMPONENTS Widget)
add_library(${PLUGIN_NAME} SHARED
notification.h
notification.cpp
notificationplugin.h
notificationplugin.cpp
${CMAKE_SOURCE_DIR}/widgets/tipswidget.h
${CMAKE_SOURCE_DIR}/widgets/tipswidget.cpp
notification.qrc
)
target_compile_definitions(${PLUGIN_NAME} PRIVATE QT_PLUGIN)
set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
target_include_directories(${PLUGIN_NAME} PRIVATE
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/interfaces>
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/widgets>
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/frame/qtdbusextended>
)
target_link_libraries(${PLUGIN_NAME} PRIVATE
Dtk::Widget
Qt5::DBus
)
install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins)

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,118 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "notification.h"
#include "constants.h"
#include <QPainter>
#include <QPainterPath>
#include <QMouseEvent>
#include <QApplication>
#include <QIcon>
#include <QDBusInterface>
#include <QDBusReply>
#include <QtConcurrent/QtConcurrent>
#include <DStyle>
#include <DGuiApplicationHelper>
Q_DECLARE_LOGGING_CATEGORY(qLcPluginNotification)
DWIDGET_USE_NAMESPACE;
DCORE_USE_NAMESPACE;
Notification::Notification(QWidget *parent)
: QWidget(parent)
, m_icon(QIcon::fromTheme("notification"))
, m_notificationCount(0)
, m_dbus(nullptr)
, m_dndMode(false)
{
setMinimumSize(PLUGIN_BACKGROUND_MIN_SIZE, PLUGIN_BACKGROUND_MIN_SIZE);
connect(this, &Notification::dndModeChanged, this, &Notification::refreshIcon);
QtConcurrent::run([this](){
m_dbus.reset(new QDBusInterface("org.deepin.dde.Notification1", "/org/deepin/dde/Notification1", "org.deepin.dde.Notification1"));
// Refresh icon for the first time, cause org.deepin.dde.Notification1 might depend on dock's DBus,
// we should not call org.deepin.dde.Notification1 in the main thread before dock's dbus is initialized.
// Just refresh icon in the other thread.
QDBusReply<QDBusVariant> dnd = m_dbus->call(QLatin1String("GetSystemInfo"), QVariant::fromValue(0u));
if (!dnd.isValid()) {
qCWarning(qLcPluginNotification) << dnd.error();
} else {
m_dndMode = dnd.value().variant().toBool();
refreshIcon();
}
QDBusConnection::sessionBus().connect("org.deepin.dde.Notification1",
"/org/deepin/dde/Notification1",
"org.deepin.dde.Notification1",
"SystemInfoChanged",
this,
SLOT(onSystemInfoChanged(quint32,QDBusVariant))
);
auto recordCountVariant = m_dbus->property("recordCount");
if (!recordCountVariant.isValid()) {
qCWarning(qLcPluginNotification) << dnd.error();
} else {
setNotificationCount(recordCountVariant.toUInt());
}
QDBusConnection::sessionBus().connect("org.deepin.dde.Notification1",
"/org/deepin/dde/Notification1",
"org.deepin.dde.Notification1",
"recordCountChanged",
this,
SLOT(setNotificationCount(uint))
);
});
}
QIcon Notification::icon() const
{
return m_icon;
}
void Notification::refreshIcon()
{
m_icon = QIcon::fromTheme(dndMode() ? "notification-off" : "notification");
Q_EMIT iconRefreshed();
}
bool Notification::dndMode() const
{
return m_dndMode;
}
void Notification::setDndMode(bool dnd)
{
if (m_dbus) {
m_dbus->call(QLatin1String("SetSystemInfo"), QVariant::fromValue(0u), QVariant::fromValue(QDBusVariant(dnd)));
}
}
uint Notification::notificationCount() const
{
return m_notificationCount;
}
void Notification::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e)
QPainter p(this);
m_icon.paint(&p, rect());
}
void Notification::onSystemInfoChanged(quint32 info, QDBusVariant value)
{
if (info == 0) {
// DND mode
m_dndMode = value.variant().toBool();
Q_EMIT dndModeChanged(m_dndMode);
}
}
void Notification::setNotificationCount(uint count)
{
if (m_notificationCount == count) {
return;
}
m_notificationCount = count;
Q_EMIT this->notificationCountChanged(count);
}

View File

@ -0,0 +1,51 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#ifndef NOTIFICATION_H
#define NOTIFICATION_H
#include <DGuiApplicationHelper>
#include <QWidget>
#include <QIcon>
#include <QDBusVariant>
#include <QDBusInterface>
class Notification : public QWidget
{
Q_OBJECT
Q_PROPERTY(bool dndMode READ dndMode WRITE setDndMode NOTIFY dndModeChanged)
Q_PROPERTY(uint notificationCount READ notificationCount NOTIFY notificationCountChanged)
public:
explicit Notification(QWidget *parent = nullptr);
QIcon icon() const;
bool dndMode() const;
void setDndMode(bool dnd);
uint notificationCount() const;
Q_SIGNALS:
void iconRefreshed();
void dndModeChanged(bool dnd);
void notificationCountChanged(uint count);
public Q_SLOTS:
void refreshIcon();
private Q_SLOTS:
void onSystemInfoChanged(quint32 info, QDBusVariant value);
void setNotificationCount(uint count);
protected:
void paintEvent(QPaintEvent *e) override;
private:
QIcon m_icon;
uint m_notificationCount;
QScopedPointer<QDBusInterface> m_dbus;
bool m_dndMode;
};
#endif // NOTIFICATION_H

View File

@ -0,0 +1,4 @@
{
"api": "2.0.0",
"depends-daemon-dbus-service": "org.deepin.dde.Notification1"
}

View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/dsg/built-in-icons">
<file alias="notification.dci">icons/notification.dci</file>
<file alias="notification-off.dci">icons/notification-off.dci</file>
</qresource>
</RCC>

View File

@ -0,0 +1,182 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "notificationplugin.h"
#include <DGuiApplicationHelper>
#include <DDBusSender>
#include <QIcon>
#include <QSettings>
#include <QPainter>
Q_LOGGING_CATEGORY(qLcPluginNotification, "dock.plugin.notification")
#define PLUGIN_STATE_KEY "enable"
#define TOGGLE_DND "toggle-dnd"
#define NOTIFICATION_SETTINGS "notification-settings"
DGUI_USE_NAMESPACE
using namespace Dock;
NotificationPlugin::NotificationPlugin(QObject *parent)
: QObject(parent)
, m_pluginLoaded(false)
, m_notification(nullptr)
, m_tipsLabel(new TipsWidget)
{
m_tipsLabel->setText(tr("No messages"));
m_tipsLabel->setVisible(false);
m_tipsLabel->setAccessibleName("Notification");
m_tipsLabel->setObjectName("NotificationTipsLabel");
}
QWidget *NotificationPlugin::itemWidget(const QString &itemKey)
{
Q_UNUSED(itemKey)
return m_notification.data();
}
QWidget *NotificationPlugin::itemTipsWidget(const QString &itemKey)
{
Q_UNUSED(itemKey);
return m_tipsLabel.data();
}
void NotificationPlugin::init(PluginProxyInterface *proxyInter)
{
m_proxyInter = proxyInter;
if (!pluginIsDisable()) {
loadPlugin();
}
}
void NotificationPlugin::pluginStateSwitched()
{
m_proxyInter->saveValue(this, PLUGIN_STATE_KEY, pluginIsDisable());
refreshPluginItemsVisible();
}
bool NotificationPlugin::pluginIsDisable()
{
return !(m_proxyInter->getValue(this, PLUGIN_STATE_KEY, true).toBool());
}
const QString NotificationPlugin::itemCommand(const QString &itemKey)
{
Q_UNUSED(itemKey);
return QString("dbus-send --session --print-reply --dest=org.deepin.dde.Widgets1 /org/deepin/dde/Widgets1 org.deepin.dde.Widgets1.Toggle");
}
const QString NotificationPlugin::itemContextMenu(const QString &itemKey)
{
QList<QVariant> items;
QMap<QString, QVariant> toggleDnd;
toggleDnd["itemId"] = TOGGLE_DND;
toggleDnd["itemText"] = toggleDndText();
toggleDnd["isCheckable"] = false;
toggleDnd["isActive"] = true;
items.push_back(toggleDnd);
QMap<QString, QVariant> notificationSettings;
notificationSettings["itemId"] = NOTIFICATION_SETTINGS;
notificationSettings["itemText"] = tr("Notification settings");
notificationSettings["isCheckable"] = false;
notificationSettings["isActive"] = true;
items.push_back(notificationSettings);
QMap<QString, QVariant> menu;
menu["items"] = items;
menu["checkableMenu"] = false;
menu["singleCheck"] = false;
return QJsonDocument::fromVariant(menu).toJson();
}
void NotificationPlugin::invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked)
{
Q_UNUSED(itemKey)
Q_UNUSED(checked)
if (menuId == TOGGLE_DND) {
m_notification->setDndMode(!m_notification->dndMode());
} else if (menuId == NOTIFICATION_SETTINGS) {
DDBusSender().service("org.deepin.dde.ControlCenter1")
.path("/org/deepin/dde/ControlCenter1")
.interface("org.deepin.dde.ControlCenter1")
.method("ShowPage")
.arg(QString("notification")).call();
}
}
int NotificationPlugin::itemSortKey(const QString &itemKey)
{
const QString key = QString("pos_%1_%2").arg(itemKey).arg(Dock::Efficient);
return m_proxyInter->getValue(this, key, 3).toInt();
}
void NotificationPlugin::setSortKey(const QString &itemKey, const int order)
{
const QString key = QString("pos_%1_%2").arg(itemKey).arg(Dock::Efficient);
m_proxyInter->saveValue(this, key, order);
}
void NotificationPlugin::pluginSettingsChanged()
{
refreshPluginItemsVisible();
}
QIcon NotificationPlugin::icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType)
{
Q_UNUSED(themeType)
if (dockPart == DockPart::DCCSetting)
return QIcon::fromTheme("notification");
return m_notification->icon();
}
void NotificationPlugin::loadPlugin()
{
if (m_pluginLoaded) {
return;
}
m_pluginLoaded = true;
m_notification.reset(new Notification);
connect(m_notification.data(), &Notification::iconRefreshed, this, [this]() { m_proxyInter->itemUpdate(this, pluginName()); });
connect(m_notification.data(), &Notification::notificationCountChanged, this, &NotificationPlugin::updateTipsText);
m_proxyInter->itemAdded(this, pluginName());
}
void NotificationPlugin::refreshPluginItemsVisible()
{
if (pluginIsDisable())
{
m_proxyInter->itemRemoved(this, pluginName());
} else {
if (!m_pluginLoaded) {
loadPlugin();
return;
}
m_proxyInter->itemAdded(this, pluginName());
}
}
void NotificationPlugin::updateTipsText(uint notificationCount)
{
if (notificationCount == 0) {
m_tipsLabel->setText(tr("No messages"));
} else {
m_tipsLabel->setText(QString("%1 %2").arg(notificationCount).arg(tr("Notifications")));
}
}
QString NotificationPlugin::toggleDndText() const
{
if (m_notification->dndMode()) {
return tr("Turn off DND mode");
} else {
return tr("Turn on DND mode");
}
}
void NotificationPlugin::refreshIcon(const QString &itemKey)
{
Q_UNUSED(itemKey)
m_notification->refreshIcon();
}

View File

@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#ifndef NOTIFICATIONPLUGIN_H
#define NOTIFICATIONPLUGIN_H
#include "pluginsiteminterface.h"
#include "notification.h"
#include "tipswidget.h"
class NotificationPlugin : public QObject, public PluginsItemInterface
{
Q_OBJECT
Q_INTERFACES(PluginsItemInterface)
Q_PLUGIN_METADATA(IID "com.deepin.dock.PluginsItemInterface" FILE "notification.json")
public:
explicit NotificationPlugin(QObject *parent = nullptr);
const QString pluginName() const override { return "notification"; }
const QString pluginDisplayName() const override { return tr("Notification"); }
PluginMode status() const override { return PluginMode::Active; }
PluginType type() override { return PluginType::Normal; }
PluginFlags flags() const override { return PluginFlag::Type_Common | PluginFlag::Attribute_CanSetting; }
QString description() const override { return pluginDisplayName(); }
bool pluginIsAllowDisable() override { return true; }
void init(PluginProxyInterface *proxyInter) override;
void pluginStateSwitched() override;
bool pluginIsDisable() override;
QWidget *itemWidget(const QString &itemKey) override;
QWidget *itemTipsWidget(const QString &itemKey) override;
const QString itemCommand(const QString &itemKey) override;
const QString itemContextMenu(const QString &itemKey) override;
void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) override;
int itemSortKey(const QString &itemKey) override;
void setSortKey(const QString &itemKey, const int order) override;
void pluginSettingsChanged() override;
QIcon icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType) override;
void refreshIcon(const QString &itemKey) override;
private:
void loadPlugin();
void refreshPluginItemsVisible();
void updateTipsText(uint notificationCount);
QString toggleDndText() const;
private:
bool m_pluginLoaded;
QScopedPointer<Notification> m_notification;
QScopedPointer<Dock::TipsWidget> m_tipsLabel;
};
#endif // NOTIFICATIONPLUGIN_H

View File

@ -11,6 +11,8 @@
#include <QIcon>
#include <QSettings>
#include <QPainter>
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#define PLUGIN_STATE_KEY "enable"
@ -78,8 +80,14 @@ bool OnboardPlugin::pluginIsDisable()
const QString OnboardPlugin::itemCommand(const QString &itemKey)
{
Q_UNUSED(itemKey);
return QString("dbus-send --print-reply --dest=org.onboard.Onboard /org/onboard/Onboard/Keyboard org.onboard.Onboard.Keyboard.ToggleVisible");
auto ifc = QDBusConnection::sessionBus().interface();
return QStringLiteral(
"dbus-send --print-reply --dest=org.onboard.Onboard /org/onboard/Onboard/Keyboard org.onboard.Onboard.Keyboard.%1"
).arg(
ifc->isServiceRegistered(QStringLiteral("org.onboard.Onboard"))
? QStringLiteral("ToggleVisible") : QStringLiteral("Show")
);
}
void OnboardPlugin::invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked)
@ -138,16 +146,8 @@ void OnboardPlugin::pluginSettingsChanged()
QIcon OnboardPlugin::icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType)
{
if (dockPart == DockPart::DCCSetting) {
if (themeType == DGuiApplicationHelper::ColorType::LightType)
return QIcon(":/icons/icon/dcc_keyboard.svg");
QPixmap pixmap(":/icons/icon/dcc_keyboard.svg");
QPainter pa(&pixmap);
pa.setCompositionMode(QPainter::CompositionMode_SourceIn);
pa.fillRect(pixmap.rect(), Qt::white);
return pixmap;
}
if (dockPart == DockPart::DCCSetting)
return QIcon(":/icons/icon/dcc_keyboard.svg");
if (dockPart == DockPart::QuickPanel)
return m_onboardItem->iconPixmap(QSize(24, 24), themeType);

View File

@ -417,13 +417,13 @@ PluginsItemInterface *DockPluginController::pluginInterAt(QObject *destItem)
void DockPluginController::startLoader(PluginLoader *loader)
{
connect(loader, &PluginLoader::finished, loader, &PluginLoader::deleteLater, Qt::QueuedConnection);
connect(loader, &PluginLoader::pluginFounded, this, [ = ](const QString &pluginFile) {
connect(loader, &PluginLoader::pluginFound, this, [ = ](const QString &pluginFile) {
QPair<QString, PluginsItemInterface *> pair;
pair.first = pluginFile;
pair.second = nullptr;
m_pluginLoadMap.insert(pair, false);
});
connect(loader, &PluginLoader::pluginFounded, this, &DockPluginController::loadPlugin, Qt::QueuedConnection);
connect(loader, &PluginLoader::pluginFound, this, &DockPluginController::loadPlugin, Qt::QueuedConnection);
int delay = Utils::SettingValue("com.deepin.dde.dock", "/com/deepin/dde/dock/", "delay-plugins-time", 0).toInt();
QTimer::singleShot(delay, loader, [ = ] { loader->start(QThread::LowestPriority); });
@ -541,9 +541,7 @@ void DockPluginController::loadPlugin(const QString &pluginFile)
// NOTE(justforlxz): 插件的所有初始化工作都在init函数中进行
// loadPlugin函数是按队列执行的initPlugin函数会有可能导致
// 函数执行被阻塞。
QTimer::singleShot(1, this, [ = ] {
initPlugin(interface);
});
QMetaObject::invokeMethod(this, std::bind(&DockPluginController::initPlugin, this, interface), Qt::QueuedConnection);
}
void DockPluginController::initPlugin(PluginsItemInterface *interface)

View File

@ -38,6 +38,7 @@
#include <QPushButton>
#include <QFontMetrics>
#include <QPainter>
#include <QStringLiteral>
#define ICONWIDTH 24
#define ICONHEIGHT 24
@ -92,12 +93,22 @@ void QuickSettingItem::paintEvent(QPaintEvent *e)
painter.setClipPath(path);
// 绘制背景色
QColor backColor(Qt::white);
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::DarkType) {
backColor = Qt::black;
}
backColor.setAlphaF(0.5);
backColor.setAlphaF(0.1);
DPalette dpa = DPaletteHelper::instance()->palette(this);
painter.fillRect(rect(), backColor);
QColor borderColor(Qt::black);
borderColor.setAlphaF(0.2);
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType) {
borderColor = QColor(Qt::white);
borderColor.setAlphaF(0.15);
}
painter.save();
painter.setPen(borderColor);
painter.drawRoundedRect(rect(), RADIUS, RADIUS);
painter.restore();
}
QColor QuickSettingItem::foregroundColor() const
@ -115,6 +126,7 @@ QColor QuickSettingItem::foregroundColor() const
QuickSettingItem *QuickSettingFactory::createQuickWidget(PluginsItemInterface * const pluginInter, const QString &itemKey)
{
if (pluginInter->pluginName() == QStringLiteral("uosai")) return nullptr;
// 如果显示在面板的图标或者Widget为空则不让显示(例如电池插件)
if (!(pluginInter->flags() & PluginFlag::Type_Common))
return nullptr;

View File

@ -13,6 +13,7 @@
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMouseEvent>
#include <DApplication>
static constexpr int ICONHEIGHT = 24;
static constexpr int ICONWIDTH = 24;
@ -26,6 +27,14 @@ StandardQuickItem::StandardQuickItem(PluginsItemInterface *const pluginInter, co
, m_needPaint(true)
{
initUi();
auto app = static_cast<DApplication* >(qApp);
if (!app) {
return;
}
connect(app, &DApplication::iconThemeChanged, this, [this] {
m_needPaint = true;
doUpdate();
});
}
StandardQuickItem::~StandardQuickItem()
@ -91,6 +100,7 @@ QWidget *StandardQuickItem::iconWidget(QWidget *parent)
layout->setAlignment(Qt::AlignVCenter);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addSpacing(6);
QLabel *imageLabel = new QLabel(widget);
imageLabel->setObjectName("imageLabel");
imageLabel->setFixedHeight(ICONHEIGHT);
@ -104,7 +114,7 @@ QWidget *StandardQuickItem::iconWidget(QWidget *parent)
labelText->setFixedWidth(70);
updatePluginName(labelText);
layout->addWidget(imageLabel);
layout->addSpacing(7);
layout->addSpacing(4);
layout->addWidget(labelText);
}

View File

@ -12,6 +12,7 @@
#include <QPainter>
#include <QIcon>
#include <QMouseEvent>
#include <DIconTheme>
DGUI_USE_NAMESPACE
@ -95,12 +96,15 @@ QPixmap PowerStatusWidget::getBatteryIcon(int themeType)
.arg(plugged ? "plugged-symbolic" : "symbolic");
}
if (themeType == DGuiApplicationHelper::ColorType::LightType)
if (themeType == DGuiApplicationHelper::ColorType::DarkType) {
iconStr.append(PLUGIN_MIN_ICON_NAME);
}
const auto ratio = devicePixelRatioF();
QSize pixmapSize = QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps) ? QSize(20, 20) : (QSize(20, 20) * ratio);
QPixmap pix = QIcon::fromTheme(iconStr, QIcon::fromTheme(":/batteryicons/resources/batteryicons/" + iconStr + ".svg")).pixmap(pixmapSize);
QIcon qrcIcon = QIcon(":/batteryicons/resources/batteryicons/" + iconStr + ".svg");
QIcon finalIcon = DIconTheme::findQIcon(iconStr, qrcIcon, DIconTheme::IgnoreBuiltinIcons);
QPixmap pix = finalIcon.pixmap(pixmapSize);
pix.setDevicePixelRatio(ratio);
return pix;

View File

@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill-rule="evenodd" transform="translate(0 2)">
<g fill="#FFF" fill-rule="evenodd" transform="translate(0 2)">
<path d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon points="12 6 9 16 9 10 6 10 9 0 9 6"/>
</g>

Before

Width:  |  Height:  |  Size: 668 B

After

Width:  |  Height:  |  Size: 680 B

View File

@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="#FFF" fill-rule="evenodd" transform="translate(0 2)">
<g fill-rule="evenodd" transform="translate(0 2)">
<path d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon points="12 6 9 16 9 10 6 10 9 0 9 6"/>
</g>

Before

Width:  |  Height:  |  Size: 680 B

After

Width:  |  Height:  |  Size: 668 B

View File

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z" transform="translate(0 4)"/>
<path fill="#FFF" fill-rule="evenodd" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z" transform="translate(0 4)"/>
</svg>

Before

Width:  |  Height:  |  Size: 574 B

After

Width:  |  Height:  |  Size: 586 B

View File

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<path fill="#FFF" fill-rule="evenodd" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z" transform="translate(0 4)"/>
<path fill-rule="evenodd" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z" transform="translate(0 4)"/>
</svg>

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 574 B

View File

@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 2)">
<path fill="#FF001F" d="M1,-1.70530257e-13 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.28042769e-17,0.487164161 0.38604019,0.0644928393 0.883378875,0.00672773133 L1,-1.70530257e-13 Z" transform="translate(2 4)"/>
<path fill="#000" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#000" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
<path fill="#FFF" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#FFF" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 935 B

After

Width:  |  Height:  |  Size: 935 B

View File

@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 2)">
<path fill="#FF001F" d="M1,-1.70530257e-13 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.28042769e-17,0.487164161 0.38604019,0.0644928393 0.883378875,0.00672773133 L1,-1.70530257e-13 Z" transform="translate(2 4)"/>
<path fill="#FFF" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#FFF" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
<path fill="#000" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#000" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 935 B

After

Width:  |  Height:  |  Size: 935 B

View File

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 4)">
<path fill="#FF001F" d="M1,-3.41060513e-13 L1,-3.41060513e-13 L1,-3.41060513e-13 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.76353751e-17,0.44771525 0.44771525,-3.4095906e-13 1,-3.41060513e-13 Z" transform="translate(2 2)"/>
<path fill="#000" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z"/>
<path fill="#FFF" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 856 B

View File

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 4)">
<path fill="#FF001F" d="M1,-3.41060513e-13 L1,-3.41060513e-13 L1,-3.41060513e-13 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.76353751e-17,0.44771525 0.44771525,-3.4095906e-13 1,-3.41060513e-13 Z" transform="translate(2 2)"/>
<path fill="#FFF" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z"/>
<path fill="#000" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 856 B

View File

@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 2)">
<path fill="#FF001F" d="M2,-1.70530257e-13 L2,8 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.76353751e-17,0.44771525 0.44771525,-1.70428804e-13 1,-1.70530257e-13 L2,-1.70530257e-13 Z" transform="translate(2 4)"/>
<path fill="#000" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#000" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
<path fill="#FFF" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#FFF" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 934 B

After

Width:  |  Height:  |  Size: 934 B

View File

@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 2)">
<path fill="#FF001F" d="M2,-1.70530257e-13 L2,8 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.76353751e-17,0.44771525 0.44771525,-1.70428804e-13 1,-1.70530257e-13 L2,-1.70530257e-13 Z" transform="translate(2 4)"/>
<path fill="#FFF" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#FFF" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
<path fill="#000" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#000" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 934 B

After

Width:  |  Height:  |  Size: 934 B

View File

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 4)">
<path fill="#FF001F" d="M1,-1.70530257e-13 L2,-1.70530257e-13 L2,-1.70530257e-13 L2,8 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.76353751e-17,0.44771525 0.44771525,-1.70428804e-13 1,-1.70530257e-13 Z" transform="translate(2 2)"/>
<path fill="#000" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z"/>
<path fill="#FFF" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 862 B

View File

@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 4)">
<path fill="#FF001F" d="M1,-1.70530257e-13 L2,-1.70530257e-13 L2,-1.70530257e-13 L2,8 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.76353751e-17,0.44771525 0.44771525,-1.70428804e-13 1,-1.70530257e-13 Z" transform="translate(2 2)"/>
<path fill="#FFF" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z"/>
<path fill="#000" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 862 B

View File

@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd" transform="translate(0 2)">
<path fill="#3ACB00" d="M4.863,-1.70530257e-13 L2.55699953,7 L5,6.999 L5,8 L1,8 C0.44771525,8 6.76353751e-17,7.55228475 0,7 L0,1 C-6.76353751e-17,0.44771525 0.44771525,-1.70428804e-13 1,-1.70530257e-13 L4.863,-1.70530257e-13 Z" transform="translate(2 4)"/>
<path fill="#000" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#000" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
<path fill="#FFF" d="M7.523,2 L7.193,2.999 L3,3 C1.8954305,3 1,3.8954305 1,5 L1,11 C1,12.1045695 1.8954305,13 3,13 L8,12.999 L8,13.999 L3,14 C1.34314575,14 0,12.6568542 0,11 L0,5 C0,3.34314575 1.34314575,2 3,2 L7.523,2 Z M15,2 C16.6568542,2 18,3.34314575 18,5 L18,11 C18,12.6568542 16.6568542,14 15,14 L10.477,13.999 L10.806,12.999 L15,13 C16.1045695,13 17,12.1045695 17,11 L17,5 C17,3.8954305 16.1045695,3 15,3 L10,2.999 L10,2 L15,2 Z M20,5 L20,11 L19,11 L19,5 L20,5 Z"/>
<polygon fill="#FFF" points="12 6 9 16 9 10 6 10 9 0 9 6"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 965 B

After

Width:  |  Height:  |  Size: 965 B

Some files were not shown because too many files have changed in this diff Show More