Compare commits

...

236 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
tsic404
f408bd89f4 chore: release version 6.0.22
log: as title
2023-09-14 05:24:18 +00:00
tsic404
25194dbf13 fix: tool appAreaWidget visible
layout->count() > 0 do not mean it contains tool plugins

log: call updateToolArea instead of using layout->count() > 0 when updateWidgetStatus
2023-09-11 05:12:20 +00:00
tsic404
00369b053b fix: datetime size error
datetimedisplayer get a wrong suitableSize during position changing,
when finished reupdate suitableSize

log: update suitableSize
2023-09-11 05:12:20 +00:00
YeShanShan
0f59177248 fix: Can't hide when DockPopupWindow deactivate
We hide the popupwindow when receiving QEvent::WindowDeactivate.

Issue: https://github.com/linuxdeepin/developer-center/issues/5405
2023-09-11 10:59:58 +08:00
tsic404
f6b2044bea fix: coredump empty tray when switch postion
Fashion mode and Efficent mode has same one tray, when tray is empty and
update orientation will cause endless reseize event which case dock stack boom

log: move TrayGridView Orientation update into TrayGridView
2023-09-11 01:56:27 +00:00
tsic404
111fb6c518 fix: tray get a wrong postion after displaymode changed
log: as title
2023-09-08 03:46:29 +00:00
tsic404
38871e8b0d fix: a space on tray without trash show
the m_mainBoxLayout last call addStretch, so tary show insert into second last

log: make tray insert into second last
2023-09-07 09:43:48 +00:00
tsic404
d24429904c chore: remove useless plugin
log: as title
2023-09-07 09:42:06 +00:00
tsic404
914ddce850 chore: bump version 6.0.21
log: as title
2023-09-07 09:41:32 +00:00
tsic404
7ed222aadb fix: datetime font size error
make font size adjusted by height or width not follow system font size

log: as title
2023-09-06 06:17:24 +00:00
tsic404
3cbb828863 feat: make unrecongnized application not dock on dde-dock
some unrecongnized app like electron app will unable to start when next click.
and custom desktopfile will not be supported by new applicationmanager1

log: not dock unrecongnized application
2023-09-06 05:04:50 +00:00
tsic404
4b9b283e5c fix: dock coredump when update recentApp invisible
itemRemove signal connect direct to taskmanager thread, and it will update recentApp visible status
which access qwidget in non-main thread.

log: make recentApp visible status update in main thread.
2023-09-06 05:04:50 +00:00
tsic404
e3c3dfe94d feat: when new am avaliable do not load custom desktopfile
log: as title
2023-09-06 05:04:50 +00:00
tsic404
75ebd8a0f2 feat: use new am dbus interface
log: as title
2023-09-06 05:04:50 +00:00
YeShanShan
e14b877696 feat: Remove dock-hotspot-plugin by Conflicts
To remove dock-hotspot-plugin.

Issue: https://github.com/linuxdeepin/developer-center/issues/5415
2023-09-06 10:07:53 +08:00
YeShanShan
406c5d8539 Revert "chore: update dependencies"
This reverts commit 9f092c2d01ad64ae6ee1458ae36f937f952034d7.
2023-09-06 10:07:53 +08:00
chenhongtao
5aa27ee40f fix: click preview container not active window
it connect to a empty signal

Log:
2023-09-05 07:59:21 +00:00
tsic404
e78be366bc chore: make trash not display in default
log: as title
2023-09-05 07:59:01 +00:00
chenhongtao
2ccf74dd35 chore: support qCDebug
Log:
2023-09-04 15:19:20 +08:00
chenhongtao
41d27c5ad7 chore: commit unused qdebug, and update log format
Log:
2023-09-04 15:19:20 +08:00
chenhongtao
bdb0dc3b86 fix: brightness update, update main view slider
Log:
2023-09-04 15:19:20 +08:00
tsic404
d1b37b045a fix: add lost windowSizeChanged Signal
log: as title
2023-08-29 02:04:27 +00:00
tsic404
811fc172d7 chore: bump version 6.0.20
log: as title
2023-08-25 09:55:02 +00:00
tsic404
e4b9d8e695 fix: no displayModeChanged signal
log: as title
2023-08-25 01:29:45 +00:00
tsic404
0e5aab95f5 fix: dock autohide even trayGridWidget show
log: prevent dock hide as dde-launcher show shen trayGridWIdget show
2023-08-24 05:13:40 +00:00
tsic404
5d87a44ac4 fix: adjust the slider to set the sound multiple times
log: add a timer to set once in 50 ms
2023-08-23 08:21:54 +00:00
tsic404
9f71814849 fix: add hideModeChanged signal
log: as title
2023-08-23 03:01:33 +00:00
tsic404
e169dcf4de fix: xebmbedtary click get no response in Efficient mode
The tray in fashion mode is not the same object as the tray in efficient
mode, and only one xembedtray is vaild, so there will be a contention
between the two. The latter xembedtray who call reparent() will be the vaild
one. So drag from expandiconwidget, the xembed tray click in the efficient
mode get no response while the tray click get response when switching from
the fashion mode.

log: make tray(both fashion and efficient mode) to be one object
2023-08-18 02:19:23 +00:00
tsic404
265cbbec13 chore: bump version 6.0.19
log: as title
2023-08-10 07:15:57 +00:00
Cloud
dfe4514981 feat: add bluetooth battery
add bluetooth battery
2023-08-09 02:52:35 +00:00
tsic404
7f554a1da5 fix: coredump when open jetbrains-toolbox
initMenu failed to create menu which make m_menu is still nullptr

log: as title
2023-08-07 04:27:49 +00:00
tsic404
3da8943417 fix: not show with launcher when hide
add lost launcherFront dbus signal

log: as title
2023-08-04 16:59:05 +08:00
tsic404
e4dde7b5a1 fix: click always activate application in TrayGridWidget
expandiconwidget get focus when click tray, so it will alway activate application because lost focus.

log: set WindowDoesNotAcceptFocus for TrayGridWidget
2023-08-04 08:55:21 +00:00
tsic404
3a5f29ca28 fix: applicationpreview scale not keep aspectratio
drawPixmap will scale pixmap to fit imageRect, but not KeepAspectRatio

log: as title
2023-08-04 05:22:20 +00:00
tsic404
9011e4a125 fix: plugin set show on dock more times, also need same times call unshow
Duplication was kept when saving the configuration, the same plugin was saved multiple times,
but only one was removed when it was removed

log: remove duplication when save dconfig
2023-08-02 02:02:40 +00:00
tsic404
9f14b5f0a8 fix: some app do not display
Current entryRemove and entryAdded connection is not thread-safe. Although entryRemove before entryAdded sended,
entryRemove slot do later than entryAdded slot, which make added entry (later signal) removed by previous entryRemove signal.

log: make entryRemove and entryAdded connecttion thread-safe.
2023-08-02 01:43:00 +00:00
tsic404
1f2d150792 fix: no positionModeChanged signal
add positionModeChanged signal to dbus

log: as title
2023-08-02 01:42:34 +00:00
tsic404
cce27c4d0c chore: bump version 6.0.18
log: as title
2023-07-26 01:41:38 +00:00
tsic404
d2164e99ec fix: official chrome unable to be identified
window_patterns.json used for app in store, and it return cn.google.chrome,
whcih is not installed. So, it means that identifyWindowByRule may return a invalid appinfo.
Return nullptr if it's invalid appinfo.

implement DesktopInfo::isInstalled, and use std::copy instead of raw loop

log: fix identifyWindowByRule return a invalid appinfo
2023-07-25 03:13:41 +00:00
tsic404
167a334142 fix: dock entries not update after displaymode changed
taskmanager not connect to display mode changed signal, so it not update entries

log: as title
2023-07-24 06:52:40 +00:00
tsic404
068f35e405 chore: remove std namespace
log: as title
2023-07-24 06:52:40 +00:00
tsic404
e1a734e030 chore: bump version 6.0.17
log: as title
2023-07-18 07:35:19 +00:00
tsic404
8ca5259c1e chore: update translate
log: as title
2023-07-18 07:35:19 +00:00
tsic404
7c897e6c96 fix: dock size error when dock positon changed
dockSize not right when position changing, height or width is current potion not changed into

log: correct dockSize when dock position changed
2023-07-18 07:35:19 +00:00
tsic404
668cea52fb chore: add libxres-dev in build-depends because of using libxres
add libxres-dev

log: as title
2023-07-18 07:35:19 +00:00
tsic404
67b6fe41b8 chore: fix reuse
add frame/taskmanager/window_patterns.json into .reuse and
download GPL-3.0-or-later.txt

log:
2023-07-18 07:35:19 +00:00
tsic404
9de057e2cc refactor: add taskmanager from dde-application-manager
1. taskmanager used to identify which entry should map to window
  in x11 environmrnt, listen to xevent in anohter thread, and handle those event
when window create, destory, changed. use some way to identify which entry(desktopfile)
should mapped to changed window.
  in wayland, connected plsamawindow signal(window created destoried.
2. use taskmanager instead of dbus in old dock code

log: as title
2023-07-18 07:35:19 +00:00
tsic404
9e364902bf chore: update .gitignore add debian and build ignore
update .gitignore

log: as title
2023-07-18 07:35:19 +00:00
tsic404
5f6cacdf2a refactor: Rewrite the calling method of dock settings
Rewrite the calling method of dock settings, using the new dconfig interface instead of AM's dbus interface

log: as title
2023-07-18 07:35:19 +00:00
tsic404
eb33819302 refactor: rewrite encapsulation of the dconfig
log: as title
2023-07-18 07:35:19 +00:00
deepin-admin-bot
fae8e4436f chore: Sync by 559e91167d
sync by github workflow

Log: none
Influence: none
2023-07-10 06:14:48 +00:00
kamiyadm
101dec15ca
fix: the name of sound device shouldn't be edited (#880)
We can edit the name of sound device in the dock, it should not
be happened. Just set the item uneditable.

Log:

Co-authored-by: kamiyadm <chenhuixing@deepin.org>
2023-07-05 10:28:18 +08:00
dengbo
fb3f888157
fix: 任务栏声音面板中出现异常的悬浮提示 (#876)
取消声音面板设备悬浮提示

Log: 修复任务栏声音面板中出现异常的悬浮提示的问题
Influence: 任务栏声音面板正常显示

Co-authored-by: dengbo <dengbo@deepin.org>
2023-07-05 09:53:48 +08:00
Zhang Dingyuan
42961e5092 fix: tips font size not follow system
Closed: https://github.com/linuxdeepin/developer-center/issues/4350
2023-06-29 10:44:13 +08:00
heyuming
9f092c2d01 chore: update dependencies
加入热点插件

Log: 更新依赖
2023-06-27 14:48:11 +08:00
李成刚
78d5bdfb27 chore: chore: update translate
update translate

Log:
2023-06-27 05:34:18 +00:00
李成刚
e245821f93 fix: 修复'Brightness' 文本裁切问题
修复文本裁切问题

Log: 调整标题栏高度解决显示不全的问题
Influence: 文本显示
Resolve: https://github.com/linuxdeepin/developer-center/issues/4759
2023-06-27 05:34:18 +00:00
李成刚
e5ce99533c fix: text missing translation
text missing translation

Log: 缺少文本翻译
Influence: 文本显示
Resolve: https://github.com/linuxdeepin/developer-center/issues/4384
2023-06-27 05:34:18 +00:00
李成刚
7a7b7d9235 fix: Fix the incomplete display of text when font 20 is scaled to 1.25
修复字体20缩放1.25时的文本显示不全

Log: 调整高度解决文本内容裁切问题
Influence: 电脑协同显示区域
Resolve: https://github.com/linuxdeepin/developer-center/issues/4382
2023-06-27 05:34:18 +00:00
heyuming
70683c4800 fix: imcomplete display when dock plugin's tips text is multi-line
note: rounded corner level is 'large'

Log: 修复当dock插件的提示文本是多行时, 文本显示不全的问题
2023-06-26 14:07:07 +08:00
tsic404
32f8fe02bf fix: DGuiApplicationHelper not found
DGuiApplicationHelper has been moved into DGui, so using Dtk::Gui instead of Dtk::Widget

log: as title
2023-06-20 01:47:37 +00:00
tsic404
ec4637a430 fix: qdbusxml2cpp-fix not generate cpp code after dtkcore update
use DtkTools and DTK_XML2CPP var instead of qdbusxml2cpp-fix binary direct

log:
2023-06-20 01:47:37 +00:00
tsic404
f48785876e chore: remove QAccessible
tests has been disabled, and QAccessible is not used in right ways

log: as title
2023-05-31 03:21:28 +00:00
tsic404
223a9df0d7 fix: incorrect trash status when deleting file in other partition
The old implementation only monitor the trash folder in user's partition
It will make other partition's recycle bin out of monitor,
Now use GIO to monitor all trash and empty trash

log: Fix the trash icon status might out-of-sync in some cases
2023-05-31 03:21:28 +00:00
tsic404
c1aa1cf13c fix: adjust tray icon size to 20
16 pixel size will make tray icon be cutted and
make it to 20 will reserve 2 pixels for each side

log: make tray icon size to 20
2023-05-29 01:55:30 +00:00
tsic404
7928cd6a2e fix: make keyboard layout plugin size fixed
indicator icon size shou be fixed same as other tray icon, should not changed follow system font size.
add text change info from sourceIndicatorWidget to display indicatorWidget

log:
2023-05-29 01:55:30 +00:00
YeShanShan
5894cc8a7d fix: DockPopupWindow losing active status
It causes that child widgets doesn't have focus even though
calling setFocus.
  It was introduced by ec5c447264087420d8ec80a18e7f2bcc4f683a74.
because that DArrowRectangle has activateWindow when show.

Issue: https://pms.uniontech.com/bug-view-172773.html
2023-05-24 16:50:36 +08:00
tsic404
ab58721930 fix: dock position changed from left to bottom no date display
update dateFont size when DateTimeDisplayer size changed.

log: fix no date display on dock when postion change from left to bottom
2023-05-22 16:00:58 +08:00
hudeng
e5f7833b6a chore(CI): Update obs tag build workflow
use obs unstable package directly

log:
2023-05-22 03:05:50 +00:00
tsic404
6697f4e8c6 chore(CI): fix PKGBUILD conflicts depends
remove deepin-qt-dbus-factory

log:
2023-05-16 08:46:12 +00:00
Tsic
fffda4d9ea
chore: bump version 6.0.16 (#869)
log: bump version 6.0.16
2023-05-11 17:42:49 +08:00
ck
07b4efd267 fix: blank in the plugin area after recorder screen
deepin-screen-recorder dock 插件有 Attribute_ForceDock flag
DockPluginController 判断是否需要存在dock上的逻辑判断了这个逻辑
在 valuechanged 时重新又把该插件加入到了dock上。没有录制中该插件没有图标

Issue: https://github.com/linuxdeepin/developer-center/issues/4215
2023-05-11 17:29:26 +08:00
tsic404
ccd2d3f586 chore: bump version 6.0.15
log: bump version 6.0.15
2023-05-11 16:29:17 +08:00
chenhongtao
a36ee58753 chore: use version from cmake
Log: use version from cmake
2023-05-11 15:44:40 +08:00
tsic404
f0108d1c41 fix: timedate size issue
when the sum of the pixel dimensions of the time font and the date font is the same as the height,
leave some space so the text doesn't look too crowded.

log: adjust timedate size
2023-05-11 14:03:29 +08:00
tsic404
83f264720c fix: popupwindow misjudgment
content should not more width than screen otherwise popupwindows must be out of bounds screen

log: as title
2023-05-11 13:50:17 +08:00
tsic404
79cab3fac8 chore: update translate
update translate

log:
2023-05-11 13:03:57 +08:00
tsic404
15e5a0fadb fix: popupwindow is out of bounds at the edge of the screen
set the minimum value of x of popupwindow to the current screen
and the maximum value to the maximum x of the current screen

log:
2023-05-11 05:03:37 +00:00
deepin-admin-bot
0a103e62bd chore: Sync by 2e5e092ba3
sync by github workflow

Log: none
Influence: none
2023-05-10 01:54:32 +00:00
tsic404
48a580117a chore: bump version 6.0.14
log: bump version 6.0.14
2023-05-09 01:47:04 +00:00
tsic404
579cf0afe9 fix: sound checked item highlight do not follow theme
1. update sound icon when theme changed
2. add built-in dci resources to prevent it become a white icon when changed into theme without dci resources

log: update sound icon when theme changed
2023-05-08 09:15:41 +00:00
chenhongtao
31958dfe1b feat: use bluetooth icon from theme
Log: use bluetooth icon from theme
2023-05-08 08:31:57 +00:00
tsic404
1be4bebe0a fix: trash do not display when dock hide and readded into dock
relayout after updateToolArea otherwise plugin item size will set to 0

log:  only relayout after update visiable
2023-05-06 17:20:32 +08:00
chenhongtao
24ff57eb70 fix: popupwindow need click destkop twice to hide
Log: only not hide it when focus widget is QLineEdit
2023-05-06 16:01:32 +08:00
wangyixue
69cec726c3 fix: wrong use of dci icon
DCI iconengine will automatically switch to correct icon when theme
type changes. Application should not do anything after getting the
pixmap.

Log: fix wrong use of dci icon
2023-05-06 06:12:56 +00:00
tsic404
af35000028 fix: add multitasking-view and show-desktop dcc icon
add multitasking-view and show-desktop dcc icon

log:
2023-05-06 14:12:09 +08:00
tsic404
119d72b0ea fix: adjust sound plugin
remove old v20 code, adjust sound devices widget style
run dbus call in another thread to prevent main thread get into wait.
make deviceList item undrageble, and sound setting clickable.

log:
2023-05-06 14:11:50 +08:00
tsic404
5908ee1605 fix: set radius for tray inner window
make m_platformWindowHandle protected so subclass can connect to windowRadiusChanged signal,
which make traymainwindow radius changed follow mainwindow

log: make trymainwindows radius changed follow mainwindow
2023-05-06 13:16:56 +08:00
Zhang Dingyuan
dc77b8904d fix: window radius is not set
as title
2023-05-05 14:52:31 +08:00
tsic404
50bbc3cf01 fix: after screen-recorder finished, dock will coredump
When screen-recorder finish recording, will notify dock update item, and dock
will clean all item and readded back. But m_dragInfo->dockItem still point to
old item which has been cleaned.
So dock will coredump, while using this pointer to judge item can drag or not.

log: update m_dragInfo->dockItem pointer when dock itemCountChanged.
2023-05-05 05:21:49 +00:00
Hillwood Yang
9bfcf4580e fix: add missing library links
add missing library links

Log: Need link these libraries to make sure the build will be successful
2023-05-05 10:44:39 +08:00
rewine
cda8e2c746 fix: must set CMAKE_INSTALL_PREFIX before GNUInstallDirs
Log:
Never modify the value of CMAKE_INSTALL_PREFIX after including GNUInstallDirs ,Otherwise incorrect CMAKE_INSTALL_FULL_XXXX values will be computed
2023-05-04 06:21:23 +00:00
Stwsyburg
a1af30c814 Fix: optimize QFile operation
Catch QFile open error and add qWarning when fail

Log: optimize QFile operation
2023-04-28 10:04:17 +08:00
zsien
1b5f9554d1 fix: fcitx5 keyboard tray icon blur
Choose the pixmap that fits best in size.
Fixes linuxdeepin/developer-center#4185
2023-04-27 17:13:18 +08:00
tsic404
a074108305 chore: bump version 6.0.13
log: bump version 6.0.13
2023-04-21 01:59:36 +00:00
tsic404
e6dbaa69bb fix: update appitem position when showing from hide
dock request to hide, set old position to appitem.
so need to update appitem position when show from hide state

log:
2023-04-21 01:36:08 +00:00
tsic404
8bf079219a fix: click undock menu which make fixed_plugin hide always
The removal will actually remove the plugin, which will make the removed plugin inaccessible,
making it impossible to set the plug-in to the dock in the dde-control-center.

Therefore, instead of calling the remove method, set the plugin to hide from the dock.

log: make fixed_plugin hide instead of removal when click ondock
2023-04-20 07:19:00 +00:00
tsic404
532350f48d fix: unable drag desktop into dock
RequestDock dbus call, only local path passed into

log: fix unable drag desktop info dock and make it docked
2023-04-20 05:52:34 +00:00
chenhongtao
82caae4c83 fix: not left mouse click will also trigger the command of plugin
Log: make only Left mouse click will trigger the command of plugin
2023-04-18 13:40:53 +08:00
chenhongtao
384fdc46ba chore: bad code fix
bad indentation of else and unused count value

Log: find some bad code and fix
2023-04-18 11:33:54 +08:00
tsic404
f90bd54c1f chore: bump version 6.0.12
log: bump version 6.0.12
2023-04-17 10:37:15 +08:00
York Lee
8bbccb27b9 docs: 修改了 dde-dock/plugins/plugin-guide/plugins-developer-guide.md 的几处问题
line:579 这一段话可以放在代码块外面
	line:744 拼写错误,应该是label而不是lable
	line:780 这一段注释可以作为正文放在代码块外面
	共3处修改。

Log: 修改了 dde-dock/plugins/plugin-guide/plugins-developer-guide.md 的几处问题
2023-04-17 02:36:02 +00:00
ck
67d098ed1e fix: dci icon size incorrect
由于 dci 图标殷勤不再乘以缩放,这里不需要再次处理了
见: https://github.com/linuxdeepin/qt5integration/pull/149

Change-Id: I88b9959be0ec88fb3e420b60d7badc5aef772f1d
2023-04-17 02:10:31 +00:00
justforlxz
430e92adbc
fix: tray background color not set alpha
as title
2023-04-14 16:40:09 +08:00
tsic404
b2efe239b6 fix: SNI tray menu unable to click
when first left click SNI tray menu and app without activate to show, will get a dbus error and recall right menu
this will case menu unable to click, move recall to another thread

log: fix SNI tray menu unable to click
2023-04-14 14:09:29 +08:00
tsic404
96dcb71fdd chore: bump version 6.0.11
log: bump version 6.0.11
2023-04-14 12:23:23 +08:00
tsic404
7abeebc7eb fix: fix timedate display widget size error
when font size changed, timedate widget need to update width and height.
call DFontSizeManager only when font size changed

log: fix timedate widget size erorr
2023-04-14 11:10:22 +08:00
chenhongtao
c2ba4e4971 fix: when there is focus on dockpopupwindow, it hide
Log: fix when there is focus and dockpopupwindow hide
2023-04-12 09:08:32 +00:00
tsic404
1bb0c628f3 fix: modify the color of the area not covered by the slider
paint two roundedRect one is slider background, another is slider has covered

log:
2023-04-12 13:08:07 +08:00
dengbo
b853cfa40e
fix: 任务栏快捷面板的电池插件图标显示异常 (#822)
蓝牙插件和电源插件属于快捷面板区域插件, 不应该返回空的图标

Log: 修复任务栏快捷面板的电池插件图标显示异常的问题
Resolve: https://github.com/linuxdeepin/developer-center/issues/4004
Influence: 任务栏快捷面板显示
2023-04-12 09:57:30 +08:00
Yutao Meng
ec5c447264 feat: DockPopupWindow改用DBlurEffectWidget实现
DockPopupWindow改为使用DBlurEffectWidget来实现新的设计,以及摆脱原来DArrowRectangle出现的侧边任务栏PopupWindow圆角显示不对称的问题.

Log: DockPopupWindow改用DBlurEffectWidget实现

Signed-off-by: Yutao Meng <mengyutao@uniontech.com>
2023-04-11 08:40:17 +00:00
tsic404
6242e642bc fix: when multiscreen connected non-primary display unable to click popupwindow
when devicePixelRatio > 1, there is a gap between multiple screens,
before currentPos multiplying by the devicePixelAatio need to subtract the topleft of the current screen
and then replus the current screen topleft

log: fix wrong multiScreen click pos
2023-04-11 13:25:56 +08:00
tsic404
59f462ff09 fix: fix xembed tray flew out
xcb create window must map to xembedtray widget, otherwise the window will fly out

log: fix xembed tray fly out
2023-04-07 18:11:04 +08:00
wineee
c89b3cce44 fix: dont hide all close button
Log: 由于相关接口被移除,暂时无法正确设置 m_closeAble 属性,暂改为默认 true
Task: https://github.com/linuxdeepin/developer-center/issues/3608
2023-04-07 02:11:11 +00:00
tsic404
5743806ad8 fix: fix timedate alway request timedate format
use local var to store format, update those when got changed signals

log:
2023-04-04 15:17:42 +08:00
tsic404
89cd24ad72 fix: fix multitasking no response sometime
fix multitasking no reponse after click sometime

log:
2023-04-04 13:09:58 +08:00
tsic404
fe75a3af39 fix: fix FixedLlugin disapprear after drag
after drag nothing deal with item update

log:
2023-04-04 13:09:58 +08:00
wangyixue
b69a220b05 fix: disk popup does not hide
Disk popup does hide after all disks are ejected. Hide popup of a
pluin in itemRemoved, and notify the DockPopupWindow to hide too.

Log: fix disk popup does not hide
Issue: 3813
2023-04-04 11:20:47 +08:00
tsic404
0781957e4e chore: bump version to 6.0.10
[ bugfix ]
  * fix: dock active color not follow dde-control-center
  * fix: tray overhanging text
  * fix: tray always reset while dragging quickItem to tray
  * fix: splash preview container
  * fix: unmute when changed volume
  * fix: expandwidget tray item can be selected
  * fix: plugin back button not support hiDPI
  * fix: bluetooth not refresh button
  * fix: Icon of trashs  is too large in small dock
  * fix: radius for tray background
  * fix: abnormal display of sound output device list
  * fix: launcher shown in a wrong location while multi screens connected
  * fix: multitasking unable to remove
  * fix: unable call selected app preview window

log:
2023-03-29 18:08:01 +08:00
tsic404
614588f630 chore(CI): add OBS workflows
add OBS workflows and modify PKGBUILD support OBS build

log:
2023-03-28 11:32:30 +08:00
dengbo
e4276da661 fix: 任务栏图标样式显示异常
任务栏图标的高亮色跟随系统主题高亮色变化

Log: 修复任务栏图标样式显示异常的问题
Resolve: https://github.com/linuxdeepin/developer-center/issues/3921
Influence: 任务栏图标显示
2023-03-26 19:16:20 +08:00
tsic404
4a67d10770 chore: fix build warning
fix package warning
1. replace deprecated QPalette::ColorRole Background and Foreground
2. replace deprecated Qt::SystemLocaleLongDate
3. replace deprecated QMouseEvent constructor
4. CMakeLists.txt rectification

log: remove build warnings
2023-03-26 19:16:00 +08:00
heyuming
32bdd7be5e fix: dock crashed while gragging sniItem
Log: 修复拖拽sni控件时引起的dock崩溃
2023-03-24 14:53:23 +08:00
heyuming
83865c93de fix: set limit width to textLabel to correct text elide behavior
Log: 设置宽度限制以纠正文本省略行为
2023-03-23 09:56:03 +08:00
heyuming
9661d3568f fix: tray always reset while dragging quickItem to trayDock
resolve: https://github.com/linuxdeepin/developer-center/issues/3915

Log: 修复拖动快捷插件到托盘上时托盘总被重置的问题
2023-03-22 11:03:46 +08:00
heyuming
2dcd8ce83e chore: update to C++17
Log: 升级到C++17
2023-03-22 10:13:44 +08:00
heyuming
102cd25748 fix: incorrect dbus xml parameter
Log: 修复不正确的dbus xml参数
2023-03-22 10:13:44 +08:00
heyuming
79d7fb9e0f fix: fix quick control panel display text incorrectly when fontSize set to 20
修复dde-dock的逻辑,但自定义插件需要各应用自己修复相关逻辑

Log: 修复当字体大小设置为20时控制面板字体显示错误
2023-03-21 13:49:28 +08:00
tsic404
e7b1bf420e fix: 修复预览花屏问题
更改传递tmp下文件描述符为管道文件描述符,使用管道传递预览图片数据

log: 修复预览花屏问题
2023-03-16 20:25:20 +08:00
heyuming
64fe544d0c fix: tray menu is hidden before function call
Log: 修复托盘在菜单中的行为被调用前被隐藏
2023-03-15 14:07:52 +08:00
Zhang Dingyuan
c65ddcdbc9 fix: mute icon not sync changed
add signal
2023-03-15 04:32:30 +00:00
Zhang Dingyuan
09b5434d3c fix: unmute when changed volume
Closed: https://github.com/linuxdeepin/developer-center/issues/3812
2023-03-15 04:32:30 +00:00
tsic404
c92497ce03 fix: remove tray item selected status
expandIcon can't be drag but can be selected,
selected status generated by undraggable expandIcon.
by removing selectable attr, selected status will
never generated.

log:
2023-03-15 02:54:24 +00:00
tsic404
8f88b6bec5 chore: use DDE for current desktop name
使用DDE作为当前桌面环境的名称

log:
2023-03-15 01:47:29 +00:00
tsic404
7a8f2c835a fix: fix some window preview crash
get a QImage copy data to prevent XDestroyImage clear image data which make a empty QImage

log:
2023-03-14 09:13:03 +00:00
Zhang Dingyuan
e8fc0b7735 fix: plugin back button not support hiDPI
Closed: https://github.com/linuxdeepin/developer-center/issues/3748
2023-03-14 06:19:03 +00:00
Zhang Dingyuan
6102475daf fix: bluetooth not refresh button
Closed: https://github.com/linuxdeepin/developer-center/issues/3809
2023-03-14 05:05:54 +00:00
Ye ShanShan
e9674ff8f5 fix: Trash's icon is too large in small dock
Modify Trash Icon's calculation way, which is flowing on LauncherItem.

Issue: https://github.com/linuxdeepin/developer-center/issues/3588
2023-03-14 09:48:22 +08:00
Ye ShanShan
2ff4a236a6 fix: Missing radius for tray's background
Add a common function to draw special background.
  Sub widget request a highlight background for parent.

Issue: https://github.com/linuxdeepin/developer-center/issues/3744
2023-03-14 09:03:34 +08:00
chenhongtao
cfa53d0b1e chore: remove some deprecated function
Log: remove deprecated function
2023-03-13 16:18:12 +08:00
chenhongtao
649dc72742 chore: chmod -x source files
Log: chmod -x
2023-03-10 16:04:32 +08:00
chenhongtao
cf14d9879f fix: layout parent
one widget should only have one layout,
others should not mark parent as this

Log: fix layout parent
2023-03-10 16:04:32 +08:00
zsien
53e68b9435 fix: abnormal display of sound output device list
Delete custom delegates and use the native DListView state.
* Fix abnormal display of checked icons
* Fix abnormal display of edit box.

Fixes linuxdeepin/developer-center#3793
Fixes linuxdeepin/developer-center#3741
2023-03-10 12:55:45 +08:00
zsien
36adcd8fc0 fix: 修复任务栏圆角跟随窗口圆角变化
Fixes linuxdeepin/developer-center#3601
2023-03-10 11:20:06 +08:00
tsic404
8f661d8d8b fix: AA_EnableHighDpiScaling setted after QGuiApplication constructed.
According to Qt's documentation https://doc.qt.io/qt-5/qt.html#ApplicationAttribute-enum
AA_EnableHighDpiScaling need to be set before QGuiApplication constructed.

log:
2023-03-09 13:01:54 +08:00
chenhongtao
724edd7514 chore: move configure to CMAKE_CURRENT_BINARY_DIR
Log: move configure location
2023-03-07 10:11:12 +08:00
tsic404
c7a02a8719 fix: fix launcher show at a worng postion when using multi screen
dock only set postion calculated by current screen
without curren screen x,y offset from top-left.

log: fix launcher appears in the wrong place
2023-03-03 12:27:06 +08:00
Felix Yan
2cb2a682c6 chore: correct typos in trashwidget.cpp
Correct typos in trashwidget.cpp
2023-02-23 14:43:03 +08:00
dengbo
7320406161
fix: 任务栏时间右键菜单时间格式显示错误 (#781)
当更改了时间显示格式后,需要更新下menu菜单的显示状态

Log: 修复任务栏时间右键菜单时间格式显示错误的问题
Resolve: https://github.com/linuxdeepin/developer-center/issues/3792
Influence: 任务栏时间插件右键菜单
2023-02-23 13:03:46 +08:00
hillwoodroc
ff7d85a556 fix: build failure
Fix reference to 'DRegionMonitor' is ambiguous

Log:
2023-02-22 10:32:39 +08:00
Felix Yan
3a6c41c1ea chore: correct a typo in popupcontrolwidget.cpp
Correct a typo in popupcontrolwidget.cpp
2023-02-21 21:40:52 +08:00
dengbo
4ebedb53d2
fix: 控制中心设置的电源选项任务栏未生效 (#779)
任务栏电源配置原来管理gsetting配置替换成dconfig配置

Log: 修复控制中心设置的电源选项任务栏未生效的问题
Bug: https://github.com/linuxdeepin/developer-center/issues/3768
Influence: 任务栏电池信息显示
2023-02-21 15:57:42 +08:00
dengbo
16ca6eaee9
fix: 任务栏多任务视图不能正常移除 (#771)
1.通过任务栏右键移除按钮时,移除对应插件
2.显示桌面和多任务视图需要加入到快捷插件显示中

Log: 修复任务栏多任务视图不能正常移除的问题
Bug: https://github.com/linuxdeepin/developer-center/issues/3599
Influence: 任务栏显示桌面合多任务视图插件的显示
2023-02-21 13:47:38 +08:00
dengbo
67c66658ee
fix: 任务栏窗口预览功能失效 (#774)
任务栏预览窗口的接口使用错误

Log: 修复任务栏窗口预览功能失效的问题
Bug: https://github.com/linuxdeepin/developer-center/issues/3779
Influence: 任务栏应用窗口预览
2023-02-20 17:40:07 +08:00
linxin
3f8593835d fix: 关闭窗口特效后,任务栏托盘窗口出现四个黑角
任务栏托盘窗口实现采用的是自定义绘制,与窗口特效不兼容,改用继承DBlurEffectWidget类的方式实现窗口

Log: 修改托盘窗口绘制方式
Bug: https://github.com/linuxdeepin/developer-center/issues/3615
2023-02-20 14:46:37 +08:00
Tsic
d57ec415cd
fix(build): fix CMakeLists merge error (#772)
fix CMakelists error and use find_pacakge Dwayland
fix archlinux build dep

log:
2023-02-20 02:36:55 +00:00
657 changed files with 27116 additions and 25146 deletions

View File

@ -8,10 +8,8 @@ concurrency:
jobs:
backup-to-gitlabwh:
uses: linuxdeepin/.github/.github/workflows/backup-to-gitlabwh.yml@master
secrets:
BRIDGETOKEN: ${{ secrets.BRIDGETOKEN }}
secrets: inherit
backup-to-gitee:
uses: linuxdeepin/.github/.github/workflows/backup-to-gitee.yml@master
secrets:
GITEE_SYNC_TOKEN: ${{ secrets.GITEE_SYNC_TOKEN }}
secrets: inherit

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

View File

@ -1,17 +0,0 @@
name: Call build-deb
on:
pull_request_target:
paths-ignore:
- ".github/workflows/**"
types: [ opened, closed, synchronize ]
concurrency:
group: ${{ github.workflow }}-pull/${{ github.event.number }}
cancel-in-progress: true
jobs:
check_job:
if: github.event.action != 'closed' || github.event.pull_request.merged
uses: linuxdeepin/.github/.github/workflows/build-deb.yml@master
secrets:
BridgeToken: ${{ secrets.BridgeToken }}

View File

@ -10,8 +10,4 @@ on:
jobs:
check_job:
uses: linuxdeepin/.github/.github/workflows/build-distribution.yml@master
secrets:
BUILD_GPG_PRIVATE_KEY: ${{ secrets.BUILD_GPG_PRIVATE_KEY }}
BUILD_SSH_PRIVATE_KEY: ${{ secrets.BUILD_SSH_PRIVATE_KEY }}
WEBDAV_PASSWD: ${{ secrets.WEBDAV_PASSWD }}
WEBDAV_USER: ${{ secrets.WEBDAV_USER }}
secrets: inherit

View File

@ -6,5 +6,4 @@ on:
jobs:
chatopt:
uses: linuxdeepin/.github/.github/workflows/chatOps.yml@master
secrets:
APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
secrets: inherit

View File

@ -12,5 +12,4 @@ concurrency:
jobs:
clacheck:
uses: linuxdeepin/.github/.github/workflows/cla-check.yml@master
secrets:
APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
secrets: inherit

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

@ -1,13 +0,0 @@
name: tag build
on:
push:
tags: "*"
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
jobs:
build:
uses: linuxdeepin/.github/.github/workflows/tag-build.yml@master
secrets: inherit

View File

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- run: export
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false

13
.gitignore vendored
View File

@ -13,6 +13,7 @@
*.a
build*/
obj-*-linux-gnu/
*.pro.user*
CMakeLists.txt.user*
*.DS_Store
@ -26,3 +27,15 @@ dde-dock
*/dbusinterface/generation_dbus_interface/
*/*/dbusinterface/generation_dbus_interface/
.transifexrc
.cache
# debain
debian/.debhelper/
debian/dde-dock/
debian/dde-dock-dev/
debian/dde-dock-onboard-plugin/
debian/tmp/
debian/*.log
debian/*.substvars
debian/debhelper-build-stamp
debian/files

50
.obs/workflows.yml Normal file
View File

@ -0,0 +1,50 @@
test_build:
steps:
- link_package:
source_project: deepin:Develop:dde
source_package: %{SCM_REPOSITORY_NAME}
target_project: deepin:CI
- configure_repositories:
project: deepin:CI
repositories:
- name: deepin_develop
paths:
- target_project: deepin:CI
target_repository: deepin_develop
architectures:
- x86_64
- aarch64
- name: debian
paths:
- target_project: deepin:CI
target_repository: debian_sid
architectures:
- x86_64
- name: archlinux
paths:
- target_project: deepin:CI
target_repository: archlinux
architectures:
- x86_64
filters:
event: pull_request
tag_build:
steps:
- trigger_services:
project: deepin:Unstable:dde
package: %{SCM_REPOSITORY_NAME}
filters:
event: tag_push
commit_build:
steps:
- trigger_services:
project: deepin:Develop:dde
package: %{SCM_REPOSITORY_NAME}
filters:
event: push

View File

@ -4,7 +4,7 @@ Upstream-Contact: UnionTech Software Technology Co., Ltd. <>
Source: https://github.com/linuxdeepin/dde-dock
# ci
Files: .github/* .gitlab-ci.yml
Files: .github/* .gitlab-ci.yml .obs/*
Copyright: None
License: CC0-1.0
@ -24,7 +24,7 @@ Copyright: UnionTech Software Technology Co., Ltd.
License: LGPL-3.0-or-later
# png svg
Files: plugins/*.png plugins/*.svg frame/*.svg tests/*.png tests/*.svg
Files: plugins/*.png plugins/*.svg frame/*.svg tests/*.png tests/*.svg plugins/*.dci
Copyright: UnionTech Software Technology Co., Ltd.
License: LGPL-3.0-or-later
@ -39,7 +39,8 @@ Copyright: None
License: CC0-1.0
# xml toml json policy yaml
Files: gschema/*.xml plugins/*.xml frame/*.xml .clog.toml plugins/*.json configs/*.json .packit.yaml .tx/config .tx/deepin.conf plugins/overlay-warning/com.deepin.dde.dock.overlay.policy plugins/dcc-dock-plugin/.tx/config
Files: gschema/*.xml plugins/*.xml frame/*.xml .clog.toml plugins/*.json configs/*.json .packit.yaml .tx/config .tx/deepin.conf plugins/overlay-warning/com.deepin.dde.dock.overlay.policy plugins/dcc-dock-plugin/.tx/config
frame/taskmanager/window_patterns.json
Copyright: None
License: CC0-1.0
@ -62,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 @@
[main]
host = https://www.transifex.com
[deepin-desktop-environment.dde-dock]
[o:linuxdeepin:p:deepin-desktop-environment:r:dde-dock]
file_filter = translations/dde-dock_<lang>.ts
minimum_perc = 0
source_file = translations/dde-dock.ts

View File

@ -1,2 +1,2 @@
[transifex]
branch = m20
branch = m23

View File

@ -1,18 +1,20 @@
cmake_minimum_required(VERSION 3.7)
cmake_minimum_required(VERSION 3.16)
if (NOT DEFINED VERSION)
set(VERSION 4.0)
set(VERSION 6.0.37)
endif()
project(dde-dock)
find_package(DtkTools REQUIRED)
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_PTHREADS_INIT 1)
set(CMAKE_PREFER_PTHREAD_FLAG ON)
#set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
@ -31,6 +33,10 @@ endif()
# generate a compile commands file as complete database for vim-YouCompleteMe or some other similar tools
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Install settings
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX /usr)
endif ()
include(GNUInstallDirs)
if (NOT (${CMAKE_BUILD_TYPE} MATCHES "Debug"))
@ -64,13 +70,13 @@ function(generation_dbus_interface xmldir outdir)
string(REPLACE "." "_" classname ${classname})
string(TOLOWER ${classname} filename)
execute_process(COMMAND qdbusxml2cpp-fix -c ${classname} -p ${outdir}/${filename} ${XMLFILE}
execute_process(COMMAND ${DTK_XML2CPP} -c ${classname} -p ${outdir}/${filename} ${XMLFILE}
WORKING_DIRECTORY ${outdir})
endforeach()
endfunction(generation_dbus_interface)
file(GLOB INTERFACES "interfaces/*.h")
add_definitions(-DCVERSION="${VERSION}")
#include使
#CMakeListsCMakeLists
#
@ -130,11 +136,6 @@ add_subdirectory("frame")
add_subdirectory("plugins")
#add_subdirectory("tests")
# Install settings
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX /usr)
endif ()
## qm files
file(GLOB QM_FILES "translations/*.qm")
install(FILES ${QM_FILES}
@ -149,10 +150,10 @@ install(FILES ${CMAKE_BINARY_DIR}/dde-dock.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
configure_file(
${CMAKE_SOURCE_DIR}/cmake/DdeDock/DdeDockConfig.cmake.in
${CMAKE_SOURCE_DIR}/cmake/DdeDock/DdeDockConfig.cmake
${CMAKE_SOURCE_DIR}/cmake/DdeDock/DdeDockConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/DdeDockConfig.cmake
@ONLY)
install(FILES "cmake/DdeDock/DdeDockConfig.cmake"
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/DdeDockConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/DdeDock)
install(FILES gschema/com.deepin.dde.dock.module.gschema.xml

View File

@ -0,0 +1,232 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for software and other kinds of works.
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and modification follow.
TERMS AND CONDITIONS
0. Definitions.
“This License” refers to version 3 of the GNU General Public License.
“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
A “covered work” means either the unmodified Program or a work based on the Program.
To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
1. Source Code.
The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
7. Additional Terms.
“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
11. Patents.
A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 (at your option) 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 <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.
You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <https://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -2,34 +2,36 @@
pkgname=deepin-dock-git
pkgver=5.5.9.r54.g49d37a6c0
pkgrel=1
sourcename=dde-dock
sourcetars=("$sourcename"_"$pkgver".tar.xz)
sourcedir="$sourcename"
pkgdesc='Deepin desktop-environment - dock module'
arch=('x86_64' 'aarch64')
url="https://github.com/linuxdeepin/dde-dock"
license=('LGPL-3.0-or-later')
depends=('qt5-svg' 'deepin-daemon-git' 'deepin-qt5integration-git'
'deepin-qt-dbus-factory-git' 'libdbusmenu-qt5')
makedepends=('git' 'cmake' 'ninja' 'qt5-tools' 'gtest' 'gmock'
'dtkcommon-git' 'dtkcore-git' 'deepin-qt5integration-git'
'deepin-qt-dbus-factory' 'libdbusmenu-qt5'
'deepin-control-center-git')
'deepin-qt-dbus-factory-git' 'libdbusmenu-qt5' 'dtkcommon-git'
'dtkcore-git' 'deepin-qt5integration-git'
'libdbusmenu-qt5' 'deepin-control-center-git' 'dwayland-git')
makedepends=('git' 'cmake' 'ninja' 'qt5-tools' 'gtest' 'gmock' 'extra-cmake-modules')
conflicts=('deepin-dock')
provides=('deepin-dock')
optdepends=('deepin-network-core-git')
groups=('deepin-git')
source=('source.tar.gz')
source=("${sourcetars[@]}")
sha512sums=('SKIP')
prepare() {
cd $deepin_source_name
cd $sourcedir
}
build() {
cd $deepin_source_name
cd $sourcedir
cmake . -GNinja -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib -DDOCK_TRAY_USE_NATIVE_POPUP=YES
ninja
}
package() {
cd $deepin_source_name
cd $sourcedir
DESTDIR="$pkgdir" ninja install
}

View File

@ -1,40 +0,0 @@
{
"magic":"dsg.config.meta",
"version":"1.0",
"contents":{
"Dock_Show_Window_name":{
"value":0,
"serial":0,
"flags":"",
"name":"小窗口显示窗口名称",
"name[zh_CN]":"小窗口显示窗口名称",
"description[zh_CN]":" \
\
\
",
"description":"0 Mouse over show;1 Always show; 2 Always hide",
"permissions":"readwrite",
"visibility":"public"
},
"Dock_Quick_Plugins": {
"value": ["power", "network", "shutdown", "trash"],
"serial": 0,
"flags": [],
"name": "显示在任务栏上的快捷插件",
"name[zh_CN]": "*****",
"description": "记录哪些插件的图标在任务栏启动的时候显示在任务栏上",
"permissions": "readwrite",
"visibility": "private"
},
"Dock_Quick_Tray_Name": {
"value": ["fcitx", "indicator:keybord_layout"],
"serial": 0,
"flags": [],
"name": "显示在任务栏上的托盘图标",
"name[zh_CN]": "任务栏上固定的托盘图标",
"description": "记录哪些托盘的图标在任务栏启动的时候显示在任务栏上",
"permissions": "readwrite",
"visibility": "private"
}
}
}

View File

@ -0,0 +1,197 @@
{
"magic": "dsg.config.meta",
"version": "1.0",
"contents": {
"Window_Size_Fashion": {
"value": 48,
"serial": 0,
"flags": [],
"name": "Window_Size_Fashion",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Icon_Size": {
"value": 36,
"serial": 0,
"flags": [],
"name": "Icon_Size",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Position": {
"value": "bottom",
"serial": 0,
"flags": [],
"name": "Position",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Hide_Timeout": {
"value": 0,
"serial": 0,
"flags": [],
"name": "Hide_Timeout",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Hide_Mode": {
"value": "keep-showing",
"serial": 0,
"flags": [],
"name": "Hide_Mode",
"name[zh_CN]": "*****",
"description": "The value will influence when the dock is shown or hidden.",
"permissions": "readwrite",
"visibility": "private"
},
"Show_Timeout": {
"value": 100,
"serial": 0,
"flags": [],
"name": "Show_Timeout",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Window_Size_Efficient": {
"value": 40,
"serial": 0,
"flags": [],
"name": "Window_Size_Efficient",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Plugin_Settings": {
"value": "{}",
"serial": 0,
"flags": [],
"name": "Plugin_Settings",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Docked_Apps": {
"value": ["/usr/share/applications/dde-file-manager", "/usr/share/applications/uos-browser", "/usr/share/applications/org.deepin.browser", "/usr/share/applications/deepin-appstore", "/usr/share/applications/deepin-app-store", "/usr/share/applications/com.deepin.store.intranet", "/usr/share/applications/deepin-album", "/usr/share/applications/deepin-music", "/usr/share/applications/deepin-contacts", "/usr/share/applications/dde-calendar", "/usr/share/applications/dde-control-center"],
"serial": 0,
"flags": [],
"name": "Docked_Apps",
"name[zh_CN]": "*****",
"description": "The default apps which is docked when dock is started.",
"permissions": "readwrite",
"visibility": "private"
},
"Win_Icon_Preferred_Apps": {
"value": ["apps.com.qq.im", "deepin.com.qq.im", "apps.com.qq.im.light", "apps.com.qq.b.eim", "apps.com.qq.rtxclient"],
"serial": 0,
"flags": [],
"name": "Win_Icon_Preferred_Apps",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Delay_Plugins_Time": {
"value": 0,
"serial": 0,
"flags": [],
"name": "Delay_Plugins_Time",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Force_Quit_App": {
"value": "enabled",
"serial": 0,
"flags": [],
"name": "Force_Quit_App",
"name[zh_CN]": "*****",
"description": "",
"permissions": "readwrite",
"visibility": "private"
},
"Display_Mode": {
"value": "fashion",
"serial": 0,
"flags": [],
"name": "Display_Mode",
"name[zh_CN]": "*****",
"description": "The dock gets different display mode, for instance, dock looks like win7 taskbar on classic mode.",
"permissions": "readwrite",
"visibility": "private"
},
"Recent_App": {
"value": [],
"serial": 0,
"flags": [],
"name": "Recent_App",
"name[zh_CN]": "*****",
"description": "The apps which has been opened recently when dock is started",
"permissions": "readwrite",
"visibility": "private"
},
"Show_Recent": {
"value": false,
"serial": 0,
"flags": [],
"name": "Show_Recent",
"name[zh_CN]": "*****",
"description": "show or hide recent app in dock",
"permissions": "readwrite",
"visibility": "private"
},
"Show_MultiWindow": {
"value": false,
"serial": 0,
"flags": [],
"name": "Show_MultiWindow",
"name[zh_CN]": "*****",
"description": "show or hide Multi Window in dock when the Entry has subWindow",
"permissions": "readwrite",
"visibility": "private"
},
"Dock_Show_Window_name":{
"value":0,
"serial":0,
"flags":"",
"name":"小窗口显示窗口名称",
"name[zh_CN]":"小窗口显示窗口名称",
"description[zh_CN]": "提供鼠标悬停小窗口标题显示配置,默认为悬停显示: \n 当配置为全部显示时,鼠标悬停在任务栏图标位置时所有预览窗口显示标题信息; \n 当配置为悬停显示时,鼠标仅在悬停在预览小窗口时在当前窗口显示标题信息; \n当配置为不显示时鼠标悬停应用位置和预览小窗口位置时都不显示标题信息",
"description":"0 Mouse over show;1 Always show; 2 Always hide",
"permissions":"readwrite",
"visibility":"public"
},
"Dock_Quick_Plugins": {
"value": ["power", "network", "shutdown", "show-desktop", "multitasking", "notification", "uosai"],
"serial": 0,
"flags": [],
"name": "Quick Plugins show on dock",
"name[zh_CN]": "显示在任务栏上的快捷插件",
"description": "记录哪些插件的图标在任务栏启动的时候显示在任务栏上",
"permissions": "readwrite",
"visibility": "private"
},
"Dock_Quick_Tray_Name": {
"value": ["fcitx", "indicator:keybord_layout"],
"serial": 0,
"flags": [],
"name": "Tray icons show on dock",
"name[zh_CN]": "任务栏上固定的托盘图标",
"description": "记录哪些托盘的图标在任务栏启动的时候显示在任务栏上",
"permissions": "readwrite",
"visibility": "private"
}
}
}

View File

@ -0,0 +1,46 @@
{
"magic": "dsg.config.meta",
"version": "1.0",
"contents": {
"control": {
"value": false,
"serial": 0,
"flags": [],
"name": "contorl",
"name[zh_CN]": "控制",
"description": "阻止鼠标事件",
"permissions": "readwrite",
"visibility": "private"
},
"enable": {
"value": true,
"serial": 0,
"flags": [],
"name": "enable",
"name[zh_CN]": "使能",
"description": "使能电源管理模块。",
"permissions": "readwrite",
"visibility": "private"
},
"showtimetofull":{
"value": true,
"serial": 0,
"flags": [],
"name": "showtimetofull",
"name[zh_CN]": "显示完整时间",
"description": "是否显示电池使用时间/剩余充电时间。",
"permissions": "readwrite",
"visibility": "public"
},
"menu-enable":{
"value": true,
"serial": 0,
"flags": [],
"name": "menu-enable",
"name[zh_CN]": "使能菜单",
"description": "使能菜单。",
"permissions": "readwrite",
"visibility": "private"
}
}
}

279
debian/changelog vendored
View File

@ -1,3 +1,282 @@
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
* fix: coredump empty tray when switch postion
* fix: Can't hide when DockPopupWindow deactivate(Issue: https://github.com/linuxdeepin/developer-center/issues/5405)
* fix: datetime size error
* fix: tool appAreaWidget visible
-- tsic404 <liuheng@deepin.org> Mon, 11 Sep 2023 13:14:25 +0800
dde-dock (6.0.21) unstable; urgency=medium
* fix: add lost windowSizeChanged Signal
* fix: brightness update, update main view slider
* chore: make trash not display in default
* fix: click preview container not active window
* feat: Remove dock-hotspot-plugin by Conflicts
* feat: use new am dbus interface
* feat: when new am avaliable do not load custom desktopfile
* fix: dock coredump when update recentApp invisible
* feat: make unrecongnized application not dock on dde-dock
* fix: datetime font size error
-- tsic404 <liuheng@deepin.org> Wed, 06 Sep 2023 14:20:11 +0800
dde-dock (6.0.20) unstable; urgency=medium
* fix: xebmbedtary click get no response in Efficient mode
* fix: add hideModeChanged signal
* fix: adjust the slider to set the sound multiple times
* fix: dock autohide even trayGridWidget show
-- tsic404 <liuheng@deepin.org> Thu, 24 Aug 2023 15:30:37 +0800
dde-dock (6.0.19) unstable; urgency=medium
* fix: no positionModeChanged signal
* fix: some app do not display
* fix: plugin set show on dock more times, also need same times call unshow
* fix: applicationpreview scale not keep aspectratio
* fix: click always activate application in TrayGridWidget
* fix: not show with launcher when hide
* fix: coredump when open jetbrains-toolbox
-- Tsic404 <liuheng@deepin.org> Mon, 07 Aug 2023 17:08:30 +0800
dde-dock (6.0.18) unstable; urgency=medium
* fix: dock entries not update after displaymode changed
* fix: official chrome unable to be identified
-- Deepin Packages Builder <liuheng@deepin.org> Mon, 24 Jul 2023 16:20:32 +0800
dde-dock (6.0.17) unstable; urgency=medium
* fix: dock position changed from left to bottom no date display
* fix: DockPopupWindow losing active status(Issue: #172773)
* fix: make keyboard layout plugin size fixed
* fix: adjust tray icon size to 20
* fix: incorrect trash status when deleting file in other partition
* fix: imcomplete display when dock plugin's tips text is multi-line
* fix: Fix the incomplete display of text when font 20 is scaled to 1.25(Influence: 电脑协同显示区域)
* fix: text missing translation(Influence: 文本显示)
* fix: 修复'Brightness' 文本裁切问题(Influence: 文本显示)
* chore: chore: update translate
* chore: update dependencies
* fix: tips font size not follow system
* fix: 任务栏声音面板中出现异常的悬浮提示 (#876)
* fix: the name of sound device shouldn't be edited (#880)
* refactor: rewrite encapsulation of the dconfig
* refactor: Rewrite the calling method of dock settings
* chore: update .gitignore add debian and build ignore
* feat: add taskmanager from dde-application-manager
* fix: dock size error when dock positon changed
-- Deepin Packages Builder <packages@deepin.org> Tue, 11 Jul 2023 09:50:13 +0800
dde-dock (6.0.16) unstable; urgency=medium
* fix: blank in the plugin area after recorder screen
-- tsic404 <liuheng@deepin.org> Thu, 11 May 2023 17:30:39 +0800
dde-dock (6.0.15) unstable; urgency=medium
* update translate
* fix: timedate size is too full
* fix: popupwindow is out of bounds at the edge of the screen
-- Tsic404 <liuheng@deepin.org> Thu, 11 May 2023 15:02:33 +0800
dde-dock (6.0.14) unstable; urgency=medium
* fix: trash do not display when dock hide and trash readded into dock
* fix: popupwindow need click destkop twice to hide
* fix: sound plugin style adjust
* fix: window radius
* fix: coredump after screen recorder finished, when drag something
* fix: fcitx5 keyboard tray icon blur
-- Tsic404 <liuheng@deepin.org> Sat, 06 May 2023 16:59:15 +0800
dde-dock (6.0.13) unstable; urgency=medium
* fix appitem indicator wrong position
* fix fixed_plugin unable to show after click undock
* fix desktopfile unable drag into dock and make it docked
-- Tsic404 <liuheng@deepin.org> Fri, 21 Apr 2023 09:39:23 +0800
dde-dock (6.0.12) unstable; urgency=medium
* fix sni tray unable to click after first left click
* adjust contol panel style
* do not handle dci scale
-- Tsic404 <liuheng@deepin.org> Mon, 17 Apr 2023 10:01:13 +0800
dde-dock (6.0.11) unstable; urgency=medium
* fix: timedate display widget size error
* fix: when there is focus on dockpopupwindow, it hide
* fix: modify the color of the area not covered by the slider
* fix: dont hide all close button(Task: 3608)
* fix: abnormally display battery plug-in in the quick-trays
* fix: when multiscreen connected non-primary display unable to click popupwindow
* fix: xembed tray flew out
* fix: dont hide all close button
* fix: timedate alway request timedate format
* fix: multitasking no response sometime
* fix: FixedLlugin disapprear after drag
* fix: disk popup does not hide(Issue: 3813)
feat: DockPopupWindow reimplemeted by DBlurEffectWidget
-- Tsic404 <liuheng@deepin.org> Fri, 14 Apr 2023 11:30:52 +0800
dde-dock (6.0.10) unstable; urgency=medium
[ bugfix ]
* fix: dock active color not follow dde-control-center
* fix: tray overhanging text
* fix: tray always reset while dragging quickItem to tray
* fix: splash preview container
* fix: unmute when changed volume
* fix: expandwidget tray item can be selected
* fix: plugin back button not support hiDPI
* fix: bluetooth not refresh button
* fix: Icon of trashs is too large in small dock
* fix: radius for tray background
* fix: abnormal display of sound output device list
* fix: launcher shown in a wrong location while multi screens connected
* fix: multitasking unable to remove
* fix: unable call selected app preview window
-- Tsic404 <liuheng@deepin.org> Wed, 29 Mar 2023 13:19:37 +0800
dde-dock (6.0.9.2) unstable; urgency=medium
[ TagBuilder ]

1
debian/compat vendored
View File

@ -1 +0,0 @@
9

74
debian/control vendored
View File

@ -2,70 +2,80 @@ Source: dde-dock
Section: x11
Priority: optional
Maintainer: Deepin Packages Builder <packages@deepin.com>
Build-Depends: debhelper (>= 8.0.0),
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,
libdtkwidget-dev (>=5.4.19),
libdwayland-dev,
libgmock-dev,
qttools5-dev,
libxcursor-dev,
libgsettings-qt-dev,
libgtest-dev,
libqt5svg5-dev,
libqt5waylandclient5-dev,
qtwayland5-private-dev,
libqt5x11extras5-dev,
libxcb-composite0-dev,
libxcb-damage0-dev,
libxcb-ewmh-dev,
libxcb-icccm4-dev,
libxcb-image0-dev,
libxcursor-dev,
libxdamage-dev,
libdwayland-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
dde-trash-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: ${shlibs: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

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.7)
cmake_minimum_required(VERSION 3.16)
set(BIN_NAME dde-dock)
@ -23,16 +23,20 @@ find_package(Qt5DBus REQUIRED)
find_package(Qt5Svg REQUIRED)
find_package(Qt5WaylandClient REQUIRED)
find_package(Qt5XkbCommonSupport REQUIRED)
find_package(DtkGui REQUIRED)
find_package(DtkWidget REQUIRED)
find_package(DtkCMake REQUIRED)
find_package(dbusmenu-qt5 REQUIRED)
find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
find_package(DWayland REQUIRED)
pkg_check_modules(XCB_EWMH REQUIRED xcb-image xcb-ewmh xcb-composite xtst x11 dbusmenu-qt5 xext xcursor)
pkg_check_modules(QGSettings REQUIRED gsettings-qt)
pkg_check_modules(DtkGUI REQUIRED dtkgui)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
set(Wayland_INCLUDE_DIRS /usr/include/DWayland/Client)
set(Wayland_LIBRARIES /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/libDWaylandClient.so)
pkg_check_modules(XCB_EWMH REQUIRED IMPORTED_TARGET x11 xcb xcb-icccm xcb-image xcb-ewmh xcb-composite xtst dbusmenu-qt5 xext xcursor xkbcommon xres)
pkg_check_modules(QGSettings REQUIRED IMPORTED_TARGET gsettings-qt)
pkg_check_modules(WAYLAND REQUIRED IMPORTED_TARGET wayland-client wayland-cursor wayland-egl)
# driver-manager
add_executable(${BIN_NAME}
@ -43,17 +47,8 @@ add_executable(${BIN_NAME}
target_include_directories(${BIN_NAME} PUBLIC
${DtkWidget_INCLUDE_DIRS}
${XCB_EWMH_INCLUDE_DIRS}
${Qt5Gui_PRIVATE_INCLUDE_DIRS}
${PROJECT_BINARY_DIR}
${QGSettings_INCLUDE_DIRS}
${DtkGUI_INCLUDE_DIRS}
${Qt5Svg_INCLUDE_DIRS}
${dbusmenu-qt5_INCLUDE_DIRS}
${Wayland_INCLUDE_DIRS}
${Qt5WaylandClient_INCLUDE_DIRS}
${Qt5WaylandClient_PRIVATE_INCLUDE_DIRS}
${Qt5XkbCommonSupport_PRIVATE_INCLUDE_DIRS}
../interfaces
../widgets
./dbusinterface/generation_dbus_interface
@ -86,21 +81,22 @@ target_include_directories(${BIN_NAME} PUBLIC
)
target_link_libraries(${BIN_NAME} PRIVATE
${XCB_EWMH_LIBRARIES}
${DtkWidget_LIBRARIES}
${Qt5Widgets_LIBRARIES}
${Qt5Gui_LIBRARIES}
${Qt5Concurrent_LIBRARIES}
${Qt5X11Extras_LIBRARIES}
${Qt5DBus_LIBRARIES}
${QGSettings_LIBRARIES}
${DtkGUI_LIBRARIES}
${Qt5Svg_LIBRARIES}
${Wayland_LIBRARIES}
${Qt5Wayland_LIBRARIES}
${Qt5WaylandClient_LIBRARIES}
${Qt5XkbCommonSupport_LIBRARIES}
-lpthread -lm
PkgConfig::QGSettings
PkgConfig::XCB_EWMH
PkgConfig::WAYLAND
Dtk::Gui
Qt5::Widgets
Qt5::Gui
Qt5::Concurrent
Qt5::X11Extras
Qt5::DBus
Qt5::Svg
Qt5::WaylandClient
Qt5::XkbCommonSupport
DWaylandClient
Threads::Threads
-lm
)
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "sw_64")
@ -116,4 +112,6 @@ if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
endif()
# bin
install(TARGETS ${BIN_NAME} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(TARGETS ${BIN_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
# window_patterns
install(FILES taskmanager/window_patterns.json DESTINATION ${CMAKE_INSTALL_DATADIR}/dde-dock/)

View File

@ -1,195 +0,0 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "accessibledefine.h"
#include "mainwindow.h"
#include "mainpanelcontrol.h"
#include "desktop_widget.h"
#include "tipswidget.h"
#include "dockpopupwindow.h"
#include "dragwidget.h"
#include "launcheritem.h"
#include "appitem.h"
#include "components/previewcontainer.h"
#include "pluginsitem.h"
#include "traypluginitem.h"
#include "placeholderitem.h"
#include "components/appdragwidget.h"
#include "components/appsnapshot.h"
#include "components/floatingpreview.h"
#include "snitraywidget.h"
#include "abstracttraywidget.h"
#include "indicatortraywidget.h"
#include "xembedtraywidget.h"
#include "system-trays/systemtrayitem.h"
#include "fashiontray/fashiontrayitem.h"
#include "fashiontray/fashiontraywidgetwrapper.h"
#include "fashiontray/fashiontraycontrolwidget.h"
#include "fashiontray/containers/attentioncontainer.h"
#include "fashiontray/containers/holdcontainer.h"
#include "fashiontray/containers/normalcontainer.h"
#include "fashiontray/containers/spliteranimated.h"
// 这部分由sound插件单独维护,这样做是因为在标记volumeslider这个类时,需要用到其setValue的实现,
// 但插件的源文件dock这边并没有包含,不想引入复杂的包含关系,其实最好的做法就是像sound插件这样,谁维护谁的
//#include "../plugins/sound/sounditem.h"
//#include "../plugins/sound/soundapplet.h"
//#include "../plugins/sound/sinkinputwidget.h"
//#include "../plugins/sound/componments/volumeslider.h"
//#include "../plugins/sound/componments/horizontalseparator.h"
#include "showdesktopwidget.h"
#include "datetimewidget.h"
#include "onboarditem.h"
#include "trashwidget.h"
#include "popupcontrolwidget.h"
#include "shutdownwidget.h"
#include "multitaskingwidget.h"
#include "overlaywarningwidget.h"
#include "horizontalseperator.h"
#include <DIconButton>
#include <DSwitchButton>
#include <DPushButton>
#include <DListView>
#include <DSwitchButton>
#include <DSpinner>
#include <dloadingindicator.h>
#include <QScrollBar>
DWIDGET_USE_NAMESPACE
using namespace Dock;
// 添加accessible
SET_FORM_ACCESSIBLE(MainWindow, "mainwindow")
SET_BUTTON_ACCESSIBLE(MainPanelControl, "mainpanelcontrol")
SET_LABEL_ACCESSIBLE(TipsWidget, "tips")
SET_FORM_ACCESSIBLE(DockPopupWindow, "popupwindow")
SET_BUTTON_ACCESSIBLE(LauncherItem, "launcheritem")
SET_BUTTON_ACCESSIBLE(AppItem, "appitem")
SET_BUTTON_ACCESSIBLE(PreviewContainer, "previewcontainer")
SET_BUTTON_ACCESSIBLE(PluginsItem, m_w->pluginName())
SET_BUTTON_ACCESSIBLE(TrayPluginItem, m_w->pluginName())
SET_BUTTON_ACCESSIBLE(PlaceholderItem, "placeholderitem")
SET_BUTTON_ACCESSIBLE(AppDragWidget, "appdragwidget")
SET_BUTTON_ACCESSIBLE(AppSnapshot, "appsnapshot")
SET_BUTTON_ACCESSIBLE(FloatingPreview, "floatingpreview")
SET_BUTTON_ACCESSIBLE(XEmbedTrayWidget, m_w->itemKeyForConfig().replace("sni:", ""))
SET_BUTTON_ACCESSIBLE(IndicatorTrayWidget, m_w->itemKeyForConfig().replace("sni:", ""))
SET_BUTTON_ACCESSIBLE(SNITrayWidget, m_w->itemKeyForConfig().replace("sni:", ""))
SET_BUTTON_ACCESSIBLE(AbstractTrayWidget, m_w->itemKeyForConfig().replace("sni:", ""))
SET_BUTTON_ACCESSIBLE(SystemTrayItem, m_w->itemKeyForConfig().replace("sni:", ""))
SET_FORM_ACCESSIBLE(FashionTrayItem, "fashiontrayitem")
SET_FORM_ACCESSIBLE(FashionTrayWidgetWrapper, "fashiontraywrapper")
SET_BUTTON_ACCESSIBLE(FashionTrayControlWidget, "fashiontraycontrolwidget")
SET_FORM_ACCESSIBLE(AttentionContainer, "attentioncontainer")
SET_FORM_ACCESSIBLE(HoldContainer, "holdcontainer")
SET_FORM_ACCESSIBLE(NormalContainer, "normalcontainer")
SET_FORM_ACCESSIBLE(SpliterAnimated, "spliteranimated")
SET_FORM_ACCESSIBLE(DatetimeWidget, "plugin-datetime")
SET_FORM_ACCESSIBLE(OnboardItem, "plugin-onboard")
SET_FORM_ACCESSIBLE(TrashWidget, "plugin-trash")
SET_BUTTON_ACCESSIBLE(PopupControlWidget, "popupcontrolwidget")
SET_FORM_ACCESSIBLE(ShutdownWidget, "plugin-shutdown")
SET_FORM_ACCESSIBLE(MultitaskingWidget, "plugin-multitasking")
SET_FORM_ACCESSIBLE(ShowDesktopWidget, "plugin-showdesktop")
SET_FORM_ACCESSIBLE(OverlayWarningWidget, "plugin-overlaywarningwidget")
SET_FORM_ACCESSIBLE(QWidget, m_w->objectName().isEmpty() ? "widget" : m_w->objectName())
SET_LABEL_ACCESSIBLE(QLabel, m_w->objectName() == "notifications" ? m_w->objectName() : m_w->text().isEmpty() ? m_w->objectName().isEmpty() ? "text" : m_w->objectName() : m_w->text())
SET_BUTTON_ACCESSIBLE(DIconButton, m_w->objectName().isEmpty() ? "imagebutton" : m_w->objectName())
SET_BUTTON_ACCESSIBLE(DSwitchButton, m_w->text().isEmpty() ? "switchbutton" : m_w->text())
SET_BUTTON_ACCESSIBLE(DesktopWidget, "desktopWidget");
SET_FORM_ACCESSIBLE(HorizontalSeperator, "HorizontalSeperator");
// 几个没什么用的标记,但为了提醒大家不要遗漏标记控件,还是不要去掉
SET_FORM_ACCESSIBLE(DBlurEffectWidget, "DBlurEffectWidget")
SET_FORM_ACCESSIBLE(DListView, "DListView")
SET_FORM_ACCESSIBLE(DLoadingIndicator, "DLoadingIndicator")
SET_FORM_ACCESSIBLE(DSpinner, "DSpinner")
SET_FORM_ACCESSIBLE(QMenu, "QMenu")
SET_FORM_ACCESSIBLE(QPushButton, "QPushButton")
SET_FORM_ACCESSIBLE(QSlider, "QSlider")
SET_FORM_ACCESSIBLE(QScrollBar, "QScrollBar")
SET_FORM_ACCESSIBLE(QScrollArea, "QScrollArea")
SET_FORM_ACCESSIBLE(QFrame, "QFrame")
SET_FORM_ACCESSIBLE(QGraphicsView, "QGraphicsView")
SET_FORM_ACCESSIBLE(DragWidget, "DragWidget")
QAccessibleInterface *accessibleFactory(const QString &classname, QObject *object)
{
// 自动化标记确定不需要的控件,方可加入忽略列表
const static QStringList ignoreLst = {"WirelessItem", "WiredItem", "SsidButton", "WirelessList", "AccessPointWidget"};
QAccessibleInterface *interface = nullptr;
USE_ACCESSIBLE(classname, MainWindow)
ELSE_USE_ACCESSIBLE(classname, MainPanelControl)
ELSE_USE_ACCESSIBLE(QString(classname).replace("Dock::", ""), TipsWidget)
ELSE_USE_ACCESSIBLE(classname, DockPopupWindow)
ELSE_USE_ACCESSIBLE(classname, LauncherItem)
ELSE_USE_ACCESSIBLE(classname, AppItem)
ELSE_USE_ACCESSIBLE(classname, PreviewContainer)
ELSE_USE_ACCESSIBLE(classname, PluginsItem)
ELSE_USE_ACCESSIBLE(classname, TrayPluginItem)
ELSE_USE_ACCESSIBLE(classname, PlaceholderItem)
ELSE_USE_ACCESSIBLE(classname, AppDragWidget)
ELSE_USE_ACCESSIBLE(classname, AppSnapshot)
ELSE_USE_ACCESSIBLE(classname, FloatingPreview)
ELSE_USE_ACCESSIBLE(classname, SNITrayWidget)
ELSE_USE_ACCESSIBLE(classname, AbstractTrayWidget)
ELSE_USE_ACCESSIBLE(classname, SystemTrayItem)
ELSE_USE_ACCESSIBLE(classname, FashionTrayItem)
ELSE_USE_ACCESSIBLE(classname, FashionTrayWidgetWrapper)
ELSE_USE_ACCESSIBLE(classname, FashionTrayControlWidget)
ELSE_USE_ACCESSIBLE(classname, AttentionContainer)
ELSE_USE_ACCESSIBLE(classname, HoldContainer)
ELSE_USE_ACCESSIBLE(classname, NormalContainer)
ELSE_USE_ACCESSIBLE(classname, SpliterAnimated)
ELSE_USE_ACCESSIBLE(classname, IndicatorTrayWidget)
ELSE_USE_ACCESSIBLE(classname, XEmbedTrayWidget)
ELSE_USE_ACCESSIBLE(classname, DesktopWidget)
ELSE_USE_ACCESSIBLE(classname, DatetimeWidget)
ELSE_USE_ACCESSIBLE(classname, OnboardItem)
ELSE_USE_ACCESSIBLE(classname, TrashWidget)
ELSE_USE_ACCESSIBLE(classname, PopupControlWidget)
ELSE_USE_ACCESSIBLE(classname, ShutdownWidget)
ELSE_USE_ACCESSIBLE(classname, MultitaskingWidget)
ELSE_USE_ACCESSIBLE(classname, ShowDesktopWidget)
ELSE_USE_ACCESSIBLE(classname, OverlayWarningWidget)
ELSE_USE_ACCESSIBLE(classname, QWidget)
ELSE_USE_ACCESSIBLE_BY_OBJECTNAME(classname, QLabel, "spliter_fix")
ELSE_USE_ACCESSIBLE_BY_OBJECTNAME(classname, QLabel, "spliter_app")
ELSE_USE_ACCESSIBLE_BY_OBJECTNAME(classname, QLabel, "spliter_tray")
ELSE_USE_ACCESSIBLE(classname, QLabel)
ELSE_USE_ACCESSIBLE_BY_OBJECTNAME(QString(classname).replace("Dtk::Widget::", ""), DIconButton, "closebutton-2d")
ELSE_USE_ACCESSIBLE_BY_OBJECTNAME(QString(classname).replace("Dtk::Widget::", ""), DIconButton, "closebutton-3d")
ELSE_USE_ACCESSIBLE_BY_OBJECTNAME(QString(classname).replace("Dtk::Widget::", ""), DSwitchButton, "")
ELSE_USE_ACCESSIBLE(QString(classname).replace("Dtk::Widget::", ""), DBlurEffectWidget)
ELSE_USE_ACCESSIBLE(QString(classname).replace("Dtk::Widget::", ""), DListView)
ELSE_USE_ACCESSIBLE(QString(classname).replace("Dtk::Widget::", ""), DLoadingIndicator)
ELSE_USE_ACCESSIBLE(QString(classname).replace("Dtk::Widget::", ""), DSpinner)
ELSE_USE_ACCESSIBLE(QString(classname).replace("Dtk::Widget::", ""), DSwitchButton)
ELSE_USE_ACCESSIBLE(QString(classname).replace("Dtk::Widget::", ""), DIconButton)
ELSE_USE_ACCESSIBLE(classname, QMenu)
ELSE_USE_ACCESSIBLE(classname, QPushButton)
ELSE_USE_ACCESSIBLE(classname, QSlider)
ELSE_USE_ACCESSIBLE(classname, QScrollBar)
ELSE_USE_ACCESSIBLE(classname, QScrollArea)
ELSE_USE_ACCESSIBLE(classname, QFrame)
ELSE_USE_ACCESSIBLE(classname, QGraphicsView)
ELSE_USE_ACCESSIBLE(classname, DragWidget)
ELSE_USE_ACCESSIBLE(classname, HorizontalSeperator);
if (!interface && object->inherits("QWidget") && !ignoreLst.contains(classname)) {
QWidget *w = static_cast<QWidget *>(object);
// 如果你看到这里的输出说明代码中仍有控件未兼顾到accessible功能请帮忙添加
if (w->accessibleName().isEmpty())
qWarning() << "accessibleFactory()" + QString("Class: " + classname + " cannot access");
}
return interface;
}

View File

@ -1,405 +0,0 @@
// Copyright (C) 2018 ~ 2020 Deepin Technology Co., Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// 为了方便使用,把相关定义独立出来,如有需要,直接包含这个头文件,然后使用SET_*的宏去设置,USE_*宏开启即可
// 注意对项目中出现的所有的QWidget的派生类都要再启用一次accessiblity包括qt的原生控件[qt未限制其标记名称为空的情况]
// 注意使用USE_ACCESSIBLE_BY_OBJECTNAME开启accessiblity的时候一定要再对这个类用一下USE_ACCESSIBLE否则标记可能会遗漏
#ifndef ACCESSIBLEINTERFACE_H
#define ACCESSIBLEINTERFACE_H
#include <QAccessible>
#include <QAccessibleWidget>
#include <QEvent>
#include <QMap>
#include <QString>
#include <QWidget>
#include <QObject>
#include <QMetaEnum>
#include <QMouseEvent>
#include <QApplication>
#define SEPARATOR "_"
inline QString getAccessibleName(QWidget *w, QAccessible::Role r, const QString &fallback)
{
const QString lowerFallback = fallback.toLower();
// 避免重复生成
static QMap< QObject *, QString > objnameMap;
if (!objnameMap[w].isEmpty())
return objnameMap[w];
static QMap< QAccessible::Role, QList< QString > > accessibleMap;
QString oldAccessName = w->accessibleName().toLower();
oldAccessName.replace(SEPARATOR, "");
// 按照类型添加固定前缀
QMetaEnum metaEnum = QMetaEnum::fromType<QAccessible::Role>();
QByteArray prefix = metaEnum.valueToKeys(r);
switch (r) {
case QAccessible::Button: prefix = "Btn"; break;
case QAccessible::StaticText: prefix = "Label"; break;
default: break;
}
// 再加上标识
QString accessibleName = QString::fromLatin1(prefix) + SEPARATOR;
QString objectName = w->objectName().toLower();
accessibleName += oldAccessName.isEmpty() ? (objectName.isEmpty() ?lowerFallback : objectName) : oldAccessName;
// 检查名称是否唯一
if (accessibleMap[r].contains(accessibleName)) {
if (!objnameMap.key(accessibleName)) {
objnameMap.remove(objnameMap.key(accessibleName));
objnameMap.insert(w, accessibleName);
return accessibleName;
}
// 获取编号,然后+1
int pos = accessibleName.indexOf(SEPARATOR);
int id = accessibleName.mid(pos + 1).toInt();
QString newAccessibleName;
do {
// 一直找到一个不重复的名字
newAccessibleName = accessibleName + SEPARATOR + QString::number(++id);
} while (accessibleMap[r].contains(newAccessibleName));
accessibleMap[r].append(newAccessibleName);
objnameMap.insert(w, newAccessibleName);
// 对象销毁后移除占用名称
QObject::connect(w, &QWidget::destroyed, [ = ] (QObject *obj) {
objnameMap.remove(obj);
accessibleMap[r].removeOne(newAccessibleName);
});
return newAccessibleName;
} else {
accessibleMap[r].append(accessibleName);
objnameMap.insert(w, accessibleName);
// 对象销毁后移除占用名称
QObject::connect(w, &QWidget::destroyed, [ = ] (QObject *obj) {
objnameMap.remove(obj);
accessibleMap[r].removeOne(accessibleName);
});
return accessibleName;
}
}
// 公共的功能
#define FUNC_CREATE(classname,accessibletype,accessdescription) explicit Accessible##classname(classname *w) \
: QAccessibleWidget(w,accessibletype,#classname)\
, m_w(w)\
, m_description(accessdescription)\
{}\
#define FUNC_TEXT(classname,accessiblename) QString Accessible##classname::text(QAccessible::Text t) const{\
switch (t) {\
case QAccessible::Name:\
return getAccessibleName(m_w, this->role(), accessiblename);\
case QAccessible::Description:\
return m_description;\
default:\
return QString();\
}\
}\
// button控件特有功能
#define FUNC_ACTIONNAMES(classname) QStringList Accessible##classname::actionNames() const{\
if(!m_w->isEnabled())\
return QStringList();\
return QStringList() << pressAction()<< showMenuAction();\
}\
#define FUNC_DOACTION(classname) void Accessible##classname::doAction(const QString &actionName){\
if(actionName == pressAction())\
{\
QPointF localPos = m_w->geometry().center();\
QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\
qApp->sendEvent(m_w,&event);\
}\
else if(actionName == showMenuAction())\
{\
QPointF localPos = m_w->geometry().center();\
QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\
qApp->sendEvent(m_w,&event);\
}\
}\
// Label控件特有功能
#define FUNC_TEXT_(classname) QString Accessible##classname::text(int startOffset, int endOffset) const{\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
return m_w->text();\
}\
// Slider控件特有功能
#define FUNC_CURRENTVALUE(classname) QVariant Accessible##classname::currentValue() const{\
return m_w->value();\
}\
#define FUNC_SETCURRENTVALUE(classname) void Accessible##classname::setCurrentValue(const QVariant &value){\
return m_w->setValue(value.toInt());\
}\
#define FUNC_MAXMUMVALUE(classname) QVariant Accessible##classname::maximumValue() const{\
return QVariant(m_w->maximum());\
}\
#define FUNC_FUNC_MINIMUMVALUE(classname) QVariant Accessible##classname::minimumValue() const{\
return QVariant(m_w->minimum());\
}\
// DSlider控件特有功能函数
#define FUNC_FUNC_MINIMUMSTEPSIZE(classname) QVariant Accessible##classname::minimumStepSize() const{\
return QVariant(m_w->pageStep());\
}\
#define SET_FORM_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget\
{\
public:\
FUNC_CREATE(classname,QAccessible::Form,accessdescription)\
QString text(QAccessible::Text t) const override;\
void *interface_cast(QAccessible::InterfaceType t) override{\
switch (t) {\
case QAccessible::ActionInterface:\
return static_cast<QAccessibleActionInterface*>(this);\
default:\
return nullptr;\
}\
}\
private:\
classname *m_w;\
QString m_description;\
};\
FUNC_TEXT(classname,accessiblename)\
#define SET_BUTTON_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget\
{\
public:\
FUNC_CREATE(classname,QAccessible::Button,accessdescription)\
QString text(QAccessible::Text t) const override;\
void *interface_cast(QAccessible::InterfaceType t) override{\
switch (t) {\
case QAccessible::ActionInterface:\
return static_cast<QAccessibleActionInterface*>(this);\
default:\
return nullptr;\
}\
}\
QStringList actionNames() const override;\
void doAction(const QString &actionName) override;\
private:\
classname *m_w;\
QString m_description;\
};\
FUNC_TEXT(classname,accessiblename)\
FUNC_ACTIONNAMES(classname)\
FUNC_DOACTION(classname)\
#define SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget, public QAccessibleTextInterface\
{\
public:\
FUNC_CREATE(classname,QAccessible::StaticText,accessdescription)\
QString text(QAccessible::Text t) const override;\
void *interface_cast(QAccessible::InterfaceType t) override{\
switch (t) {\
case QAccessible::ActionInterface:\
return static_cast<QAccessibleActionInterface*>(this);\
case QAccessible::TextInterface:\
return static_cast<QAccessibleTextInterface*>(this);\
default:\
return nullptr;\
}\
}\
QString text(int startOffset, int endOffset) const override;\
void selection(int selectionIndex, int *startOffset, int *endOffset) const override {\
Q_UNUSED(selectionIndex)\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
}\
int selectionCount() const override { return 0; }\
void addSelection(int startOffset, int endOffset) override {\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
}\
void removeSelection(int selectionIndex) override {\
Q_UNUSED(selectionIndex)\
}\
void setSelection(int selectionIndex, int startOffset, int endOffset) override {\
Q_UNUSED(selectionIndex)\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
}\
int cursorPosition() const override { return 0; }\
void setCursorPosition(int position) override {\
Q_UNUSED(position)\
}\
int characterCount() const override { return 0; }\
QRect characterRect(int offset) const override {\
Q_UNUSED(offset)\
return QRect();\
}\
int offsetAtPoint(const QPoint &point) const override {\
Q_UNUSED(point)\
return 0;\
}\
void scrollToSubstring(int startIndex, int endIndex) override {\
Q_UNUSED(startIndex)\
Q_UNUSED(endIndex)\
}\
QString attributes(int offset, int *startOffset, int *endOffset) const override {\
Q_UNUSED(offset)\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
return QString();\
}\
private:\
classname *m_w;\
QString m_description;\
};\
FUNC_TEXT(classname,accessiblename)\
FUNC_TEXT_(classname)\
#define SET_SLIDER_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget, public QAccessibleValueInterface\
{\
public:\
FUNC_CREATE(classname,QAccessible::Slider,accessdescription)\
QString text(QAccessible::Text t) const override;\
void *interface_cast(QAccessible::InterfaceType t) override{\
switch (t) {\
case QAccessible::ActionInterface:\
return static_cast<QAccessibleActionInterface*>(this);\
case QAccessible::ValueInterface:\
return static_cast<QAccessibleValueInterface*>(this);\
default:\
return nullptr;\
}\
}\
QVariant currentValue() const override;\
void setCurrentValue(const QVariant &value) override;\
QVariant maximumValue() const override;\
QVariant minimumValue() const override;\
QVariant minimumStepSize() const override;\
private:\
classname *m_w;\
QString m_description;\
};\
FUNC_TEXT(classname,accessiblename)\
FUNC_CURRENTVALUE(classname)\
FUNC_SETCURRENTVALUE(classname)\
FUNC_MAXMUMVALUE(classname)\
FUNC_FUNC_MINIMUMVALUE(classname)\
FUNC_FUNC_MINIMUMSTEPSIZE(classname)\
#define SET_EDITABLE_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget, public QAccessibleEditableTextInterface, public QAccessibleTextInterface\
{\
public:\
FUNC_CREATE(classname,QAccessible::EditableText,accessdescription)\
QString text(QAccessible::Text t) const override;\
QAccessibleInterface *child(int index) const override { Q_UNUSED(index); return nullptr; }\
void *interface_cast(QAccessible::InterfaceType t) override{\
switch (t) {\
case QAccessible::ActionInterface:\
return static_cast<QAccessibleActionInterface*>(this);\
case QAccessible::TextInterface:\
return static_cast<QAccessibleTextInterface*>(this);\
case QAccessible::EditableTextInterface:\
return static_cast<QAccessibleEditableTextInterface*>(this);\
default:\
return nullptr;\
}\
}\
QString text(int startOffset, int endOffset) const override;\
void selection(int selectionIndex, int *startOffset, int *endOffset) const override {\
Q_UNUSED(selectionIndex)\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
}\
int selectionCount() const override { return 0; }\
void addSelection(int startOffset, int endOffset) override {\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
}\
void removeSelection(int selectionIndex) override { Q_UNUSED(selectionIndex);}\
void setSelection(int selectionIndex, int startOffset, int endOffset) override {\
Q_UNUSED(selectionIndex)\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
}\
int cursorPosition() const override { return 0; }\
void setCursorPosition(int position) override {\
Q_UNUSED(position)\
}\
int characterCount() const override { return 0; }\
QRect characterRect(int offset) const override { \
Q_UNUSED(offset)\
return QRect(); }\
int offsetAtPoint(const QPoint &point) const override {\
Q_UNUSED(point)\
return 0; }\
void scrollToSubstring(int startIndex, int endIndex) override {\
Q_UNUSED(startIndex)\
Q_UNUSED(endIndex)\
}\
QString attributes(int offset, int *startOffset, int *endOffset) const override {\
Q_UNUSED(offset)\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
return QString(); }\
void insertText(int offset, const QString &text) override {\
Q_UNUSED(offset)\
Q_UNUSED(text)\
}\
void deleteText(int startOffset, int endOffset) override {\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
}\
void replaceText(int startOffset, int endOffset, const QString &text) override {\
Q_UNUSED(startOffset)\
Q_UNUSED(endOffset)\
Q_UNUSED(text)\
}\
private:\
classname *m_w;\
QString m_description;\
};\
FUNC_TEXT(classname,accessiblename)\
FUNC_TEXT_(classname)\
#define USE_ACCESSIBLE(classnamestring,classname) if (classnamestring == QLatin1String(#classname) && object && object->isWidgetType())\
{\
interface = new Accessible##classname(static_cast<classname *>(object));\
}\
#define ELSE_USE_ACCESSIBLE(classnamestring,classname) else if (classnamestring == QLatin1String(#classname) && object && object->isWidgetType())\
{\
interface = new Accessible##classname(static_cast<classname *>(object));\
}\
// [指定objectname]---适用同一个类但objectname不同的情况
#define USE_ACCESSIBLE_BY_OBJECTNAME(classnamestring,classname,objectname) if (classnamestring == QLatin1String(#classname) && object && (object->objectName() == objectname) && object->isWidgetType())\
{\
interface = new Accessible##classname(static_cast<classname *>(object));\
}\
#define ELSE_USE_ACCESSIBLE_BY_OBJECTNAME(classnamestring,classname,objectname) else if (classnamestring == QLatin1String(#classname) && object && (object->objectName() == objectname) && object->isWidgetType())\
{\
interface = new Accessible##classname(static_cast<classname *>(object));\
}\
/*******************************************简化使用*******************************************/
#define SET_FORM_ACCESSIBLE(classname,accessiblename) SET_FORM_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,"")
#define SET_BUTTON_ACCESSIBLE(classname,accessiblename) SET_BUTTON_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,"")
#define SET_LABEL_ACCESSIBLE(classname,accessiblename) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,"")
#define SET_SLIDER_ACCESSIBLE(classname,accessiblename) SET_SLIDER_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,"")
#define SET_EDITABLE_ACCESSIBLE(classname,accessiblename) SET_EDITABLE_ACCESSIBLE_WITH_DESCRIPTION(classname,accessiblename,"")
/************************************************************************************************/
#endif // ACCESSIBLEINTERFACE_H

View File

@ -7,8 +7,12 @@
#include "appitem.h"
#include "launcheritem.h"
#include "pluginsitem.h"
#include "taskmanager/entry.h"
#include "taskmanager/taskmanager.h"
#include "taskmanager/windowinfobase.h"
#include "traypluginitem.h"
#include "utils.h"
#include "docksettings.h"
#include "appmultiitem.h"
#include "quicksettingcontroller.h"
@ -24,24 +28,24 @@ const QGSettings *DockItemManager::m_dockedSettings = Utils::ModuleSettingsPtr("
DockItemManager::DockItemManager(QObject *parent)
: QObject(parent)
, m_appInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this))
, m_taskmanager(TaskManager::instance())
, m_loadFinished(false)
{
//固定区域:启动器
m_itemList.append(new LauncherItem);
// 应用区域
for (auto entry : m_appInter->entries()) {
AppItem *it = new AppItem(m_appInter, m_appSettings, m_activeSettings, m_dockedSettings, entry);
for (auto entry : m_taskmanager->getEntries()) {
AppItem *it = new AppItem(m_appSettings, m_activeSettings, m_dockedSettings, entry);
manageItem(it);
connect(it, &AppItem::requestActivateWindow, m_appInter, &DockInter::ActivateWindow, Qt::QueuedConnection);
connect(it, &AppItem::requestPreviewWindow, m_appInter, &DockInter::PreviewWindow);
connect(it, &AppItem::requestCancelPreview, m_appInter, &DockInter::CancelPreviewWindow);
connect(it, &AppItem::requestPreviewWindow, m_taskmanager, &TaskManager::previewWindow);
connect(it, &AppItem::requestCancelPreview, m_taskmanager, &TaskManager::cancelPreviewWindow);
connect(it, &AppItem::windowCountChanged, this, &DockItemManager::onAppWindowCountChanged);
connect(this, &DockItemManager::requestUpdateDockItem, it, &AppItem::requestUpdateEntryGeometries);
m_itemList.append(it);
m_appIDist.append(it->appId());
updateMultiItems(it);
}
@ -60,10 +64,10 @@ DockItemManager::DockItemManager(QObject *parent)
connect(quickController, &QuickSettingController::pluginLoaderFinished, this, &DockItemManager::onPluginLoadFinished, Qt::QueuedConnection);
// 应用信号
connect(m_appInter, &DockInter::EntryAdded, this, &DockItemManager::appItemAdded);
connect(m_appInter, &DockInter::EntryRemoved, this, static_cast<void (DockItemManager::*)(const QString &)>(&DockItemManager::appItemRemoved), Qt::QueuedConnection);
connect(m_appInter, &DockInter::ServiceRestarted, this, &DockItemManager::reloadAppItems);
connect(m_appInter, &DockInter::ShowMultiWindowChanged, this, &DockItemManager::onShowMultiWindowChanged);
connect(m_taskmanager, &TaskManager::entryAdded, this, &DockItemManager::appItemAdded, Qt::DirectConnection);
connect(m_taskmanager, &TaskManager::entryRemoved, this, static_cast<void (DockItemManager::*)(const QString &)>(&DockItemManager::appItemRemoved), Qt::DirectConnection);
connect(m_taskmanager, &TaskManager::serviceRestarted, this, &DockItemManager::reloadAppItems);
connect(DockSettings::instance(), &DockSettings::showMultiWindowChanged, this, &DockItemManager::onShowMultiWindowChanged);
DApplication *app = qobject_cast<DApplication *>(qApp);
if (app) {
@ -80,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)
@ -98,7 +102,7 @@ const QList<QPointer<DockItem>> DockItemManager::itemList() const
bool DockItemManager::appIsOnDock(const QString &appDesktop) const
{
return m_appInter->IsOnDock(appDesktop);
return m_taskmanager->isOnDock(appDesktop);
}
void DockItemManager::refreshItemsIcon()
@ -166,15 +170,15 @@ void DockItemManager::itemMoved(DockItem *const sourceItem, DockItem *const targ
// for app move, index 0 is launcher item, need to pass it.
if (moveType == DockItem::App && replaceType == DockItem::App)
m_appInter->MoveEntry(moveIndex - 1, replaceIndex - 1);
m_taskmanager->moveEntry(moveIndex - 1, replaceIndex - 1);
}
void DockItemManager::itemAdded(const QString &appDesktop, int idx)
{
m_appInter->RequestDock(appDesktop, idx);
m_taskmanager->requestDock(appDesktop, idx);
}
void DockItemManager::appItemAdded(const QDBusObjectPath &path, const int index)
void DockItemManager::appItemAdded(const Entry *entry, const int index)
{
// 第一个是启动器
int insertIndex = 1;
@ -188,18 +192,17 @@ void DockItemManager::appItemAdded(const QDBusObjectPath &path, const int index)
++insertIndex;
}
AppItem *item = new AppItem(m_appInter, m_appSettings, m_activeSettings, m_dockedSettings, path);
AppItem *item = new AppItem(m_appSettings, m_activeSettings, m_dockedSettings, entry);
if (m_appIDist.contains(item->appId())) {
delete item;
item->deleteLater();
return;
}
manageItem(item);
connect(item, &AppItem::requestActivateWindow, m_appInter, &DockInter::ActivateWindow, Qt::QueuedConnection);
connect(item, &AppItem::requestPreviewWindow, m_appInter, &DockInter::PreviewWindow);
connect(item, &AppItem::requestCancelPreview, m_appInter, &DockInter::CancelPreviewWindow);
connect(item, &AppItem::requestPreviewWindow, m_taskmanager, &TaskManager::previewWindow);
connect(item, &AppItem::requestCancelPreview, m_taskmanager, &TaskManager::cancelPreviewWindow);
connect(item, &AppItem::windowCountChanged, this, &DockItemManager::onAppWindowCountChanged);
connect(this, &DockItemManager::requestUpdateDockItem, item, &AppItem::requestUpdateEntryGeometries);
@ -255,8 +258,8 @@ void DockItemManager::reloadAppItems()
appItemRemoved(static_cast<AppItem *>(item.data()));
// append new item
for (auto path : m_appInter->entries())
appItemAdded(path, -1);
for (Entry* entry : m_taskmanager->getEntries())
appItemAdded(entry, -1);
}
void DockItemManager::manageItem(DockItem *item)
@ -365,11 +368,11 @@ void DockItemManager::onAppWindowCountChanged()
void DockItemManager::updateMultiItems(AppItem *appItem, bool emitSignal)
{
// 如果系统设置不开启应用多窗口拆分,则无需之后的操作
if (!m_appInter->showMultiWindow())
if (!m_taskmanager->showMultiWindow())
return;
// 如果开启了多窗口拆分,则同步窗口和多窗口应用的信息
const WindowInfoMap &windowInfoMap = appItem->windowsMap();
const WindowInfoMap &windowInfoMap = appItem->windowsInfos();
QList<AppMultiItem *> removeItems;
// 同步当前已经存在的多开窗口的列表,删除不存在的多开窗口
for (int i = 0; i < m_itemList.size(); i++) {
@ -430,7 +433,7 @@ bool DockItemManager::needRemoveMultiWindow(AppMultiItem *multiItem) const
// 查找多分窗口对应的窗口在应用所有的打开的窗口中是否存在,只要它对应的窗口存在,就无需删除
// 只要不存在,就需要删除
AppItem *appItem = multiItem->appItem();
const WindowInfoMap &windowInfoMap = appItem->windowsMap();
const WindowInfoMap &windowInfoMap = appItem->windowsInfos();
for (auto it = windowInfoMap.begin(); it != windowInfoMap.end(); it++) {
if (it.key() == multiItem->winId())
return false;
@ -441,7 +444,7 @@ bool DockItemManager::needRemoveMultiWindow(AppMultiItem *multiItem) const
void DockItemManager::onShowMultiWindowChanged()
{
if (m_appInter->showMultiWindow()) {
if (m_taskmanager->showMultiWindow()) {
// 如果当前设置支持窗口多开那么就依次对每个APPItem加载多开窗口
for (int i = 0; i < m_itemList.size(); i++) {
const QPointer<DockItem> &dockItem = m_itemList[i];

View File

@ -11,6 +11,8 @@
#include "appitem.h"
#include "placeholderitem.h"
#include "dbusutil.h"
#include "taskmanager/taskmanager.h"
#include "taskmanager/windowinfobase.h"
#include <QObject>
@ -56,7 +58,7 @@ private Q_SLOTS:
private:
explicit DockItemManager(QObject *parent = nullptr);
void appItemAdded(const QDBusObjectPath &path, const int index);
void appItemAdded(const Entry *entry, const int index);
void appItemRemoved(const QString &appId);
void appItemRemoved(AppItem *appItem);
void updatePluginsItemOrderKey();
@ -69,7 +71,7 @@ private:
bool needRemoveMultiWindow(AppMultiItem *multiItem) const;
private:
DockInter *m_appInter;
TaskManager *m_taskmanager;
static DockItemManager *INSTANCE;

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

@ -4,6 +4,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "recentapphelper.h"
#include "dockitemmanager.h"
#include "appitem.h"
#include <QWidget>
@ -12,14 +13,14 @@
#define ENTRY_NORMAL 1
#define ENTRY_RECENT 2
RecentAppHelper::RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, DockInter *dockInter, QObject *parent)
RecentAppHelper::RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, QObject *parent)
: QObject(parent)
, m_appWidget(appWidget)
, m_recentWidget(recentWidget)
, m_dockInter(dockInter)
{
m_appWidget->installEventFilter(this);
m_recentWidget->installEventFilter(this);
connect(this, &RecentAppHelper::requestUpdateRecentVisible, this, &RecentAppHelper::updateRecentVisible, Qt::QueuedConnection);
}
void RecentAppHelper::setDisplayMode(Dock::DisplayMode displayMode)
@ -71,11 +72,6 @@ bool RecentAppHelper::dockAppIsVisible() const
|| m_appWidget->layout()->count() > 0);
}
void RecentAppHelper::updateDockInter(DockInter *dockInter)
{
m_dockInter = dockInter;
}
bool RecentAppHelper::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_appWidget || watched == m_recentWidget) {
@ -175,7 +171,7 @@ void RecentAppHelper::removeRecentAreaItem(DockItem *wdg)
{
QBoxLayout *recentLayout = static_cast<QBoxLayout *>(m_recentWidget->layout());
recentLayout->removeWidget(wdg);
updateRecentVisible();
Q_EMIT requestUpdateRecentVisible();
}
void RecentAppHelper::removeAppAreaItem(DockItem *wdg)
@ -193,7 +189,7 @@ int RecentAppHelper::getEntryIndex(DockItem *dockItem, QWidget *widget) const
return -1;
// 查找当前的应用在所有的应用中的排序
QStringList entryIds = m_dockInter->GetEntryIDs();
QStringList entryIds = TaskManager::instance()->getEntryIDs();
int index = entryIds.indexOf(appItem->appId());
if (index < 0)
return -1;

View File

@ -24,19 +24,19 @@ class RecentAppHelper : public QObject
Q_OBJECT
public:
explicit RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, DockInter *dockInter, QObject *parent = nullptr);
explicit RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, QObject *parent = nullptr);
void setDisplayMode(Dock::DisplayMode displayMode);
void resetAppInfo();
void addAppItem(int index, DockItem *appItem);
void removeAppItem(DockItem *dockItem);
bool recentIsVisible() const;
bool dockAppIsVisible() const;
void updateDockInter(DockInter *dockInter);
Q_SIGNALS:
void requestUpdate();
void recentVisibleChanged(bool); // 最近区域是否可见发生变化的信号
void dockAppVisibleChanged(bool); // 驻留应用区域是否可见发生变化的信号
void requestUpdateRecentVisible();
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
@ -45,7 +45,6 @@ private:
bool appInRecent(DockItem *item) const;
void addAppAreaItem(int index, DockItem *wdg);
void addRecentAreaItem(int index, DockItem *wdg);
void updateRecentVisible();
void updateDockAppVisible(bool lastVisible);
void removeRecentAreaItem(DockItem *wdg);
@ -57,12 +56,12 @@ private:
private Q_SLOTS:
void onModeChanged(int mode);
void updateRecentVisible();
private:
QWidget *m_appWidget;
QWidget *m_recentWidget;
Dock::DisplayMode m_displayMode;
DockInter *m_dockInter;
};
#endif // RECENTAPPHELPER_H

View File

@ -45,6 +45,7 @@ void ToolAppHelper::setPosition(Position position)
{
m_toolAreaWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
m_position = position;
updateWidgetStatus();
}
bool ToolAppHelper::toolIsVisible() const
@ -60,8 +61,6 @@ void ToolAppHelper::appendToToolArea(int index, DockItem *dockItem)
boxLayout->insertWidget(index, dockItem);
else
boxLayout->addWidget(dockItem);
Q_EMIT requestUpdate();
}
bool ToolAppHelper::removeToolArea(PluginsItemInterface *itemInter)
@ -142,7 +141,7 @@ void ToolAppHelper::updateWidgetStatus()
m_toolAreaWidget->setVisible(false);
} else {
// 时尚模式
m_toolAreaWidget->setVisible(m_toolAreaWidget->layout()->count() > 0);
updateToolArea();
}
bool visible = toolIsVisible();
if (oldVisible != visible)

View File

@ -25,7 +25,8 @@
#include "windowmanager.h"
#include "quicksettingcontroller.h"
#include "pluginsitem.h"
#include "settingconfig.h"
#include "docksettings.h"
#include "common.h"
#include "customevent.h"
#include <DGuiApplicationHelper>
@ -174,7 +175,7 @@ DockItemInfos DBusDockAdaptors::plugins()
// 获取本地加载的插件
QList<PluginsItemInterface *> allPlugin = localPlugins();
DockItemInfos pluginInfos;
QStringList quickSettingKeys = SETTINGCONFIG->value(DOCK_QUICK_PLUGINS).toStringList();
QStringList quickSettingKeys = DockSettings::instance()->getQuickPlugins();
for (PluginsItemInterface *plugin : allPlugin) {
DockItemInfo info;
info.name = plugin->pluginName();
@ -271,13 +272,12 @@ void DBusDockAdaptors::setPluginVisible(const QString &pluginName, bool visible)
void DBusDockAdaptors::setItemOnDock(const QString settingKey, const QString &itemKey, bool visible)
{
QStringList settings = SETTINGCONFIG->value(settingKey).toStringList();
if (visible && !settings.contains(itemKey))
settings << itemKey;
else if (!visible && settings.contains(itemKey))
settings.removeOne(itemKey);
SETTINGCONFIG->setValue(settingKey, settings);
DockSettings *settings = DockSettings::instance();
if ( keyQuickTrayName == settingKey) {
visible? settings->setTrayItemOnDock(itemKey) : settings->removeTrayItemOnDock(itemKey);
} else if (keyQuickPlugins == settingKey) {
visible? settings->setQuickPlugin(itemKey) : settings->removeQuickPlugin(itemKey);
}
}
QRect DBusDockAdaptors::geometry() const
@ -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

@ -91,6 +91,7 @@ class DBusDockAdaptors: public QDBusAbstractAdaptor
" <arg name=\"visible\" type=\"b\" direction=\"in\"/>"
" </method>"
" <method name=\"setItemOnDock\">"
" <arg name=\"settingKey\" type=\"s\" direction=\"in\"/>"
" <arg name=\"itemKey\" type=\"s\" direction=\"in\"/>"
" <arg name=\"visible\" type=\"b\" direction=\"in\"/>"
" </method>"

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

@ -1,16 +0,0 @@
<interface name="dde.dock.ClientManager">
<method name="ActivateWindow">
<arg type="u" direction="in"></arg>
<arg type="b" direction="out"></arg>
</method>
<method name="CloseWindow">
<arg type="u" direction="in"></arg>
<arg type="b" direction="out"></arg>
</method>
<method name="CurrentActiveWindow">
<arg type="u" direction="out"></arg>
</method>
<signal name="ActiveWindowChanged">
<arg type="u"></arg>
</signal>
</interface>

View File

@ -1,13 +0,0 @@
<interface name="dde.dock.Entry">
<method name="Activate">
</method>
<signal name="DataChanged">
<arg type="s"></arg>
<arg type="s"></arg>
</signal>
<property name="Id" type="s" access="read"></property>
<property name="Type" type="s" access="read"></property>
<property name="Data" type="a{ss}" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="Dict"/>
</property>
</interface>

View File

@ -0,0 +1,246 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "dockdaemonadaptors.h"
#include "docksettings.h"
#include "taskmanager/taskmanager.h"
DockDaemonDBusAdaptor::DockDaemonDBusAdaptor(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
// constructor
setAutoRelaySignals(true);
connect(TaskManager::instance(), &TaskManager::entryAdded, this, &DockDaemonDBusAdaptor::EntryAdded);
connect(TaskManager::instance(), &TaskManager::entryRemoved, this, &DockDaemonDBusAdaptor::EntryRemoved);
connect(TaskManager::instance(), &TaskManager::hideStateChanged, this, &DockDaemonDBusAdaptor::HideStateChanged);
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);
connect(DockSettings::instance(), &DockSettings::windowSizeEfficientChanged, this, &DockDaemonDBusAdaptor::WindowSizeEfficientChanged);
connect(DockSettings::instance(), &DockSettings::windowSizeFashionChanged, this, &DockDaemonDBusAdaptor::WindowSizeFashionChanged);
}
DockDaemonDBusAdaptor::~DockDaemonDBusAdaptor()
{
// destructor
}
int DockDaemonDBusAdaptor::displayMode() const
{
return TaskManager::instance()->getDisplayMode();
}
void DockDaemonDBusAdaptor::setDisplayMode(int value)
{
if (displayMode() != value) {
TaskManager::instance()->setDisplayMode(value);
Q_EMIT DisplayModeChanged(value);
}
}
QStringList DockDaemonDBusAdaptor::dockedApps() const
{
return TaskManager::instance()->getDockedApps();
}
int DockDaemonDBusAdaptor::hideMode() const
{
return TaskManager::instance()->getHideMode();
}
void DockDaemonDBusAdaptor::setHideMode(int value)
{
if (hideMode() != value) {
TaskManager::instance()->setHideMode(static_cast<HideMode>(value));
Q_EMIT HideModeChanged(value);
}
}
int DockDaemonDBusAdaptor::hideState() const
{
return TaskManager::instance()->getHideState();
}
uint DockDaemonDBusAdaptor::hideTimeout() const
{
return TaskManager::instance()->getHideTimeout();
}
void DockDaemonDBusAdaptor::setHideTimeout(uint value)
{
if (hideTimeout() != value) {
TaskManager::instance()->setHideTimeout(value);
Q_EMIT HideTimeoutChanged(value);
}
}
uint DockDaemonDBusAdaptor::windowSizeEfficient() const
{
return TaskManager::instance()->getWindowSizeEfficient();
}
void DockDaemonDBusAdaptor::setWindowSizeEfficient(uint value)
{
if (windowSizeEfficient() != value) {
TaskManager::instance()->setWindowSizeEfficient(value);
Q_EMIT WindowSizeEfficientChanged(value);
}
}
uint DockDaemonDBusAdaptor::windowSizeFashion() const
{
return TaskManager::instance()->getWindowSizeFashion();
}
void DockDaemonDBusAdaptor::setWindowSizeFashion(uint value)
{
if (windowSizeFashion() != value) {
TaskManager::instance()->setWindowSizeFashion(value);
Q_EMIT WindowSizeFashionChanged(value);
}
}
uint DockDaemonDBusAdaptor::windowMargin() const
{
return TaskManager::instance()->windowMargin();
}
QRect DockDaemonDBusAdaptor::frontendWindowRect() const
{
return TaskManager::instance()->getFrontendWindowRect();
}
uint DockDaemonDBusAdaptor::iconSize() const
{
return TaskManager::instance()->getIconSize();
}
void DockDaemonDBusAdaptor::setIconSize(uint value)
{
if (iconSize() != value) {
TaskManager::instance()->setIconSize(value);
Q_EMIT IconSizeChanged(value);
}
}
int DockDaemonDBusAdaptor::position() const
{
return TaskManager::instance()->getPosition();
}
void DockDaemonDBusAdaptor::setPosition(int value)
{
if (position() != value) {
TaskManager::instance()->setPosition(value);
Q_EMIT PositionChanged(value);
}
}
uint DockDaemonDBusAdaptor::showTimeout() const
{
return TaskManager::instance()->getShowTimeout();
}
void DockDaemonDBusAdaptor::setShowTimeout(uint value)
{
if (showTimeout() != value) {
TaskManager::instance()->setShowTimeout(value);
Q_EMIT ShowTimeoutChanged(value);
}
}
bool DockDaemonDBusAdaptor::showRecent() const
{
return DockSettings::instance()->showRecent();
}
bool DockDaemonDBusAdaptor::showMultiWindow() const
{
return TaskManager::instance()->showMultiWindow();
}
void DockDaemonDBusAdaptor::CloseWindow(uint win)
{
TaskManager::instance()->closeWindow(win);
}
// for debug
QStringList DockDaemonDBusAdaptor::GetEntryIDs()
{
return TaskManager::instance()->getEntryIDs();
}
bool DockDaemonDBusAdaptor::IsDocked(const QString &desktopFile)
{
return TaskManager::instance()->isDocked(desktopFile);
}
bool DockDaemonDBusAdaptor::IsOnDock(const QString &desktopFile)
{
return TaskManager::instance()->isOnDock(desktopFile);
}
void DockDaemonDBusAdaptor::MoveEntry(int index, int newIndex)
{
TaskManager::instance()->moveEntry(index, newIndex);
}
QString DockDaemonDBusAdaptor::QueryWindowIdentifyMethod(uint win)
{
return TaskManager::instance()->queryWindowIdentifyMethod(win);
}
QStringList DockDaemonDBusAdaptor::GetDockedAppsDesktopFiles()
{
return TaskManager::instance()->getDockedAppsDesktopFiles();
}
QString DockDaemonDBusAdaptor::GetPluginSettings()
{
return TaskManager::instance()->getPluginSettings();
}
void DockDaemonDBusAdaptor::SetPluginSettings(QString jsonStr)
{
TaskManager::instance()->setPluginSettings(jsonStr);
}
void DockDaemonDBusAdaptor::MergePluginSettings(QString jsonStr)
{
TaskManager::instance()->mergePluginSettings(jsonStr);
}
void DockDaemonDBusAdaptor::RemovePluginSettings(QString key1, QStringList key2List)
{
TaskManager::instance()->removePluginSettings(key1, key2List);
}
bool DockDaemonDBusAdaptor::RequestDock(const QString &desktopFile, int index)
{
return TaskManager::instance()->requestDock(desktopFile, index);
}
bool DockDaemonDBusAdaptor::RequestUndock(const QString &desktopFile)
{
return TaskManager::instance()->requestUndock(desktopFile);
}
void DockDaemonDBusAdaptor::SetShowRecent(bool visible)
{
DockSettings::instance()->setShowRecent(visible);
}
void DockDaemonDBusAdaptor::SetShowMultiWindow(bool showMultiWindow)
{
TaskManager::instance()->setShowMultiWindow(showMultiWindow);
}
void DockDaemonDBusAdaptor::SetFrontendWindowRect(int x, int y, uint width, uint height)
{
TaskManager::instance()->setFrontendWindowRect(x, y, width, height);
}

View File

@ -0,0 +1,208 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "taskmanager/entry.h"
#include <QtCore/QObject>
#include <QtCore/QMetaObject>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QDBusObjectPath>
#include <QRect>
/*
* Adaptor class for interface org.deepin.dde.daemon.Dock1
*/
class Entry;
class DockDaemonDBusAdaptor: public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.deepin.dde.daemon.Dock1")
Q_CLASSINFO("D-Bus Introspection", ""
" <interface name=\"org.deepin.dde.daemon.Dock1\">\n"
" <method name=\"CloseWindow\">\n"
" <arg direction=\"in\" type=\"u\" name=\"win\"/>\n"
" </method>\n"
" <method name=\"GetEntryIDs\">\n"
" <arg direction=\"out\" type=\"as\" name=\"list\"/>\n"
" </method>\n"
" <method name=\"IsDocked\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"IsOnDock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
" </method>\n"
" <method name=\"MoveEntry\">\n"
" <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"newIndex\"/>\n"
" </method>\n"
" <method name=\"QueryWindowIdentifyMethod\">\n"
" <arg direction=\"in\" type=\"u\" name=\"win\"/>\n"
" <arg direction=\"out\" type=\"s\" name=\"identifyMethod\"/>\n"
" </method>\n"
" <method name=\"GetDockedAppsDesktopFiles\">\n"
" <arg direction=\"out\" type=\"as\" name=\"desktopFiles\"/>\n"
" </method>\n"
" <method name=\"GetPluginSettings\">\n"
" <arg direction=\"out\" type=\"s\" name=\"jsonStr\"/>\n"
" </method>\n"
" <method name=\"SetPluginSettings\">\n"
" <arg direction=\"in\" type=\"s\" name=\"jsonStr\"/>\n"
" </method>\n"
" <method name=\"MergePluginSettings\">\n"
" <arg direction=\"in\" type=\"s\" name=\"jsonStr\"/>\n"
" </method>\n"
" <method name=\"RemovePluginSettings\">\n"
" <arg direction=\"in\" type=\"s\" name=\"key1\"/>\n"
" <arg direction=\"in\" type=\"as\" name=\"key2List\"/>\n"
" </method>\n"
" <method name=\"RequestDock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"RequestUndock\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
" </method>\n"
" <method name=\"SetShowRecent\">\n"
" <arg direction=\"in\" type=\"b\" name=\"visible\"/>\n"
" </method>\n"
" <method name=\"SetShowMultiWindow\">\n"
" <arg direction=\"in\" type=\"b\" name=\"visible\"/>\n"
" </method>\n"
" <method name=\"SetFrontendWindowRect\">\n"
" <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
" <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
" <arg direction=\"in\" type=\"u\" name=\"width\"/>\n"
" <arg direction=\"in\" type=\"u\" name=\"height\"/>\n"
" </method>\n"
" <signal name=\"ServiceRestarted\"/>\n"
" <signal name=\"EntryAdded\">\n"
" <arg type=\"o\" name=\"path\"/>\n"
" <arg type=\"i\" name=\"index\"/>\n"
" </signal>\n"
" <signal name=\"EntryRemoved\">\n"
" <arg type=\"s\" name=\"entryId\"/>\n"
" </signal>\n"
" <property access=\"readwrite\" type=\"u\" name=\"ShowTimeout\"/>\n"
" <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"
" <property access=\"read\" type=\"i\" name=\"HideState\"/>\n"
" <property access=\"readwrite\" type=\"i\" name=\"Position\"/>\n"
" <property access=\"readwrite\" type=\"u\" name=\"IconSize\"/>\n"
" <property access=\"read\" type=\"as\" name=\"DockedApps\"/>\n"
" <property access=\"read\" type=\"b\" name=\"ShowRecent\"/>\n"
" <property access=\"read\" type=\"b\" name=\"ShowMultiWindow\"/>\n"
" </interface>\n"
"")
public:
DockDaemonDBusAdaptor(QObject *parent);
virtual ~DockDaemonDBusAdaptor();
public: // PROPERTIES
Q_PROPERTY(int DisplayMode READ displayMode WRITE setDisplayMode NOTIFY DisplayModeChanged)
int displayMode() const;
void setDisplayMode(int value);
Q_PROPERTY(QStringList DockedApps READ dockedApps NOTIFY DockedAppsChanged)
QStringList dockedApps() const;
Q_PROPERTY(int HideMode READ hideMode WRITE setHideMode NOTIFY HideModeChanged)
int hideMode() const;
void setHideMode(int value);
Q_PROPERTY(int HideState READ hideState NOTIFY HideStateChanged)
int hideState() const;
Q_PROPERTY(uint HideTimeout READ hideTimeout WRITE setHideTimeout NOTIFY HideTimeoutChanged)
uint hideTimeout() const;
void setHideTimeout(uint value);
Q_PROPERTY(uint WindowSizeEfficient READ windowSizeEfficient WRITE setWindowSizeEfficient NOTIFY WindowSizeEfficientChanged)
uint windowSizeEfficient() const;
void setWindowSizeEfficient(uint value);
Q_PROPERTY(uint WindowSizeFashion READ windowSizeFashion WRITE setWindowSizeFashion NOTIFY WindowSizeFashionChanged)
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;
Q_PROPERTY(uint IconSize READ iconSize WRITE setIconSize NOTIFY IconSizeChanged)
uint iconSize() const;
void setIconSize(uint value);
Q_PROPERTY(int Position READ position WRITE setPosition NOTIFY PositionChanged)
int position() const;
void setPosition(int value);
Q_PROPERTY(uint ShowTimeout READ showTimeout WRITE setShowTimeout NOTIFY ShowTimeoutChanged)
uint showTimeout() const;
void setShowTimeout(uint value);
Q_PROPERTY(bool ShowRecent READ showRecent NOTIFY showRecentChanged)
bool showRecent() const;
Q_PROPERTY(bool ShowMultiWindow READ showMultiWindow NOTIFY ShowMultiWindowChanged)
bool showMultiWindow() const;
public Q_SLOTS: // METHODS
void CloseWindow(uint win);
QStringList GetEntryIDs();
bool IsDocked(const QString &desktopFile);
bool IsOnDock(const QString &desktopFile);
void MoveEntry(int index, int newIndex);
QString QueryWindowIdentifyMethod(uint win);
QStringList GetDockedAppsDesktopFiles();
QString GetPluginSettings();
void SetPluginSettings(QString jsonStr);
void MergePluginSettings(QString jsonStr);
void RemovePluginSettings(QString key1, QStringList key2List);
bool RequestDock(const QString &desktopFile, int index);
bool RequestUndock(const QString &desktopFile);
void SetShowRecent(bool visible);
void SetShowMultiWindow(bool showMultiWindow);
void SetFrontendWindowRect(int x, int y, uint width, uint height);
Q_SIGNALS: // SIGNALS
void ServiceRestarted();
void EntryAdded(const Entry *entry, int index);
void EntryRemoved(const QString &entryId);
void DisplayModeChanged(int value) const;
void DockedAppsChanged(const QStringList &value) const;
void EntriesChanged(const QList<QDBusObjectPath> &value) const;
void FrontendWindowRectChanged(const QRect &dockRect) const;
void HideModeChanged(int value) const;
void HideStateChanged(int value) const;
void HideTimeoutChanged(uint value) const;
void IconSizeChanged(uint value) const;
void PositionChanged(int value) const;
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

@ -1,339 +0,0 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* 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/>.
*/
#include "dockinterface.h"
#include "org_deepin_dde_daemon_dock1.h"
// 因为 types/dockrect.h 文件中定义了DockRect类而在此处也定义了DockRect
// 所以在此处先加上DOCKRECT_H宏(types/dockrect.h文件中定义的宏)来禁止包含types/dockrect.h头文件
// 否则会出现重复定义的错误
#define DOCKRECT_H
/*
* Implementation of interface class __Dock
*/
class DockPrivate
{
public:
DockPrivate() = default;
// begin member variables
int DisplayMode;
QStringList DockedApps;
QList<QDBusObjectPath> Entries;
DockRect FrontendWindowRect;
int HideMode;
int HideState;
uint HideTimeout;
uint IconSize;
double Opacity;
int Position;
uint ShowTimeout;
uint WindowSize;
uint WindowSizeEfficient;
uint WindowSizeFashion;
public:
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
QMap<QString, QList<QVariant>> m_waittingCalls;
};
// 窗管中提供的ActiveWindow接口MinimizeWindow目前还在开发过程中因此关于这两个接口暂时使用v23的后端接口
// 等窗管完成了这几个接口后删除此处v20的接口改成v23提供的新接口即可
using DockInter = org::deepin::dde::daemon::Dock1;
/**
* @brief DBUS接口是通过窗管获取的AM后端并未提供窗管的相关接口
* 使
*/
class WM : public QDBusAbstractInterface
{
public:
static inline const char *staticInterfaceName()
{ return "com.deepin.wm"; }
public:
explicit WM(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = Q_NULLPTR);
~WM();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> ActivateWindow(uint in0)
{
return m_dockInter->ActivateWindow(in0);
}
QDBusPendingReply<> MinimizeWindow(uint in0)
{
return m_dockInter->MinimizeWindow(in0);
}
inline QDBusPendingReply<> CancelPreviewWindow()
{
return asyncCallWithArgumentList(QStringLiteral("CancelPreviewWindow"), QList<QVariant>());
}
inline QDBusPendingReply<> PreviewWindow(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("CancelPreviewWindow"), argumentList);
}
private:
DockInter *m_dockInter;
};
WM::WM(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
, m_dockInter(new DockInter("org.deepin.dde.daemon.Dock1", "/org/deepin/dde/daemon/Dock1", QDBusConnection::sessionBus(), this))
{
}
WM::~WM()
{
}
Dde_Dock::Dde_Dock(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
, d_ptr(new DockPrivate)
, m_wm(new WM("com.deepin.wm", "/com/deepin/wm", QDBusConnection::sessionBus(), this))
{
QDBusConnection::sessionBus().connect(this->service(), this->path(),
"org.freedesktop.DBus.Properties",
"PropertiesChanged","sa{sv}as",
this,
SLOT(onPropertyChanged(const QDBusMessage &)));
if (QMetaType::type("DockRect") == QMetaType::UnknownType)
registerDockRectMetaType();
}
Dde_Dock::~Dde_Dock()
{
qDeleteAll(d_ptr->m_processingCalls.values());
delete d_ptr;
}
void Dde_Dock::onPropertyChanged(const QDBusMessage& msg)
{
QList<QVariant> arguments = msg.arguments();
if (3 != arguments.count())
return;
QString interfaceName = msg.arguments().at(0).toString();
if (interfaceName != staticInterfaceName())
return;
QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>());
QStringList keys = changedProps.keys();
foreach(const QString &prop, keys) {
const QMetaObject* self = metaObject();
for (int i=self->propertyOffset(); i < self->propertyCount(); ++i) {
QMetaProperty p = self->property(i);
if (p.name() == prop)
Q_EMIT p.notifySignal().invoke(this);
}
}
}
int Dde_Dock::displayMode()
{
return qvariant_cast<int>(property("DisplayMode"));
}
void Dde_Dock::setDisplayMode(int value)
{
setProperty("DisplayMode", QVariant::fromValue(value));
}
QStringList Dde_Dock::dockedApps()
{
return qvariant_cast<QStringList>(property("DockedApps"));
}
QList<QDBusObjectPath> Dde_Dock::entries()
{
return qvariant_cast<QList<QDBusObjectPath>>(property("Entries"));
}
DockRect Dde_Dock::frontendWindowRect()
{
return qvariant_cast<DockRect>(property("FrontendWindowRect"));
}
int Dde_Dock::hideMode()
{
return qvariant_cast<int>(property("HideMode"));
}
void Dde_Dock::setHideMode(int value)
{
internalPropSet("HideMode", QVariant::fromValue(value));
}
int Dde_Dock::hideState()
{
return qvariant_cast<int>(property("HideState"));
}
uint Dde_Dock::hideTimeout()
{
return qvariant_cast<uint>(property("HideTimeout"));
}
void Dde_Dock::setHideTimeout(uint value)
{
setProperty("HideTimeout", QVariant::fromValue(value));
}
uint Dde_Dock::iconSize()
{
return qvariant_cast<uint>(property("IconSize"));
}
void Dde_Dock::setIconSize(uint value)
{
setProperty("IconSize", QVariant::fromValue(value));
}
double Dde_Dock::opacity()
{
return qvariant_cast<double>(property("Opacity"));
}
void Dde_Dock::setOpacity(double value)
{
setProperty("Opacity", QVariant::fromValue(value));
}
int Dde_Dock::position()
{
return qvariant_cast<int>(property("Position"));
}
void Dde_Dock::setPosition(int value)
{
setProperty("Position", QVariant::fromValue(value));
}
uint Dde_Dock::showTimeout()
{
return qvariant_cast<uint>(property("ShowTimeout"));
}
void Dde_Dock::setShowTimeout(uint value)
{
setProperty("ShowTimeout", QVariant::fromValue(value));
}
uint Dde_Dock::windowSize()
{
return qvariant_cast<uint>(property("WindowSize"));
}
void Dde_Dock::setWindowSize(uint value)
{
setProperty("WindowSize", QVariant::fromValue(value));
}
uint Dde_Dock::windowSizeEfficient()
{
return qvariant_cast<uint>(property("WindowSizeEfficient"));
}
void Dde_Dock::setWindowSizeEfficient(uint value)
{
setProperty("WindowSizeEfficient", QVariant::fromValue(value));
}
uint Dde_Dock::windowSizeFashion()
{
return qvariant_cast<uint>(property("WindowSizeFashion"));
}
void Dde_Dock::setWindowSizeFashion(uint value)
{
setProperty("WindowSizeFashion", QVariant::fromValue(value));
}
bool Dde_Dock::showRecent() const
{
return qvariant_cast<bool>(property("ShowRecent"));
}
bool Dde_Dock::showMultiWindow() const
{
return qvariant_cast<bool>(property("ShowMultiWindow"));
}
QDBusPendingReply<> Dde_Dock::ActivateWindow(uint in0)
{
return m_wm->ActivateWindow(in0);
}
QDBusPendingReply<> Dde_Dock::PreviewWindow(uint in0)
{
return m_wm->PreviewWindow(in0);
}
QDBusPendingReply<> Dde_Dock::CancelPreviewWindow()
{
return m_wm->CancelPreviewWindow();
}
QDBusPendingReply<> Dde_Dock::MinimizeWindow(uint in0)
{
return m_wm->MinimizeWindow(in0);
}
void Dde_Dock::CallQueued(const QString &callName, const QList<QVariant> &args)
{
if (d_ptr->m_waittingCalls.contains(callName)) {
d_ptr->m_waittingCalls[callName] = args;
return;
}
if (d_ptr->m_processingCalls.contains(callName)) {
d_ptr->m_waittingCalls.insert(callName, args);
} else {
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Dde_Dock::onPendingCallFinished);
d_ptr->m_processingCalls.insert(callName, watcher);
}
}
void Dde_Dock::onPendingCallFinished(QDBusPendingCallWatcher *w)
{
w->deleteLater();
const auto callName = d_ptr->m_processingCalls.key(w);
Q_ASSERT(!callName.isEmpty());
if (callName.isEmpty())
return;
d_ptr->m_processingCalls.remove(callName);
if (!d_ptr->m_waittingCalls.contains(callName))
return;
const auto args = d_ptr->m_waittingCalls.take(callName);
CallQueued(callName, args);
}

View File

@ -1,338 +0,0 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* 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/>.
*/
#ifndef DOCK_INTERFACE
#define DOCK_INTERFACE
#include "types/dockrect.h"
#include <QObject>
#include <QByteArray>
#include <QList>
#include <QMap>
#include <QString>
#include <QStringList>
#include <QVariant>
#include <QtDBus>
/*
* Proxy class for interface org.deepin.dde.daemon.Dock1
*/
class DockPrivate;
class WM;
void registerDockRectMetaType();
class Dde_Dock : public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.deepin.dde.daemon.Dock1"; }
public:
explicit Dde_Dock(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~Dde_Dock();
Q_PROPERTY(int DisplayMode READ displayMode WRITE setDisplayMode NOTIFY DisplayModeChanged)
int displayMode();
void setDisplayMode(int value);
Q_PROPERTY(QStringList DockedApps READ dockedApps NOTIFY DockedAppsChanged)
QStringList dockedApps();
Q_PROPERTY(QList<QDBusObjectPath> Entries READ entries NOTIFY EntriesChanged)
QList<QDBusObjectPath> entries();
Q_PROPERTY(DockRect FrontendWindowRect READ frontendWindowRect NOTIFY FrontendWindowRectChanged)
DockRect frontendWindowRect();
Q_PROPERTY(int HideMode READ hideMode WRITE setHideMode NOTIFY HideModeChanged)
int hideMode();
void setHideMode(int value);
Q_PROPERTY(int HideState READ hideState NOTIFY HideStateChanged)
int hideState();
Q_PROPERTY(uint HideTimeout READ hideTimeout WRITE setHideTimeout NOTIFY HideTimeoutChanged)
uint hideTimeout();
void setHideTimeout(uint value);
Q_PROPERTY(uint IconSize READ iconSize WRITE setIconSize NOTIFY IconSizeChanged)
uint iconSize();
void setIconSize(uint value);
Q_PROPERTY(double Opacity READ opacity WRITE setOpacity NOTIFY OpacityChanged)
double opacity();
void setOpacity(double value);
Q_PROPERTY(int Position READ position WRITE setPosition NOTIFY PositionChanged)
int position();
void setPosition(int value);
Q_PROPERTY(uint ShowTimeout READ showTimeout WRITE setShowTimeout NOTIFY ShowTimeoutChanged)
uint showTimeout();
void setShowTimeout(uint value);
Q_PROPERTY(uint WindowSize READ windowSize WRITE setWindowSize NOTIFY WindowSizeChanged)
uint windowSize();
void setWindowSize(uint value);
Q_PROPERTY(uint WindowSizeEfficient READ windowSizeEfficient WRITE setWindowSizeEfficient NOTIFY WindowSizeEfficientChanged)
uint windowSizeEfficient();
void setWindowSizeEfficient(uint value);
Q_PROPERTY(uint WindowSizeFashion READ windowSizeFashion WRITE setWindowSizeFashion NOTIFY WindowSizeFashionChanged)
uint windowSizeFashion();
void setWindowSizeFashion(uint value);
Q_PROPERTY(bool ShowRecent READ showRecent NOTIFY showRecentChanged)
bool showRecent() const;
Q_PROPERTY(bool ShowMultiWindow READ showMultiWindow NOTIFY ShowMultiWindowChanged)
bool showMultiWindow() const;
public Q_SLOTS: // METHODS
QDBusPendingReply<> ActivateWindow(uint in0);
QDBusPendingReply<> PreviewWindow(uint in0);
QDBusPendingReply<> CancelPreviewWindow();
QDBusPendingReply<> MinimizeWindow(uint in0);
inline void ActivateWindowQueued(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("ActivateWindow"), argumentList);
}
inline QDBusPendingReply<> CloseWindow(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("CloseWindow"), argumentList);
}
inline void CloseWindowQueued(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("CloseWindow"), argumentList);
}
inline QDBusPendingReply<QStringList> GetDockedAppsDesktopFiles()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("GetDockedAppsDesktopFiles"), argumentList);
}
inline QDBusPendingReply<QStringList> GetEntryIDs()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("GetEntryIDs"), argumentList);
}
inline QDBusPendingReply<QString> GetPluginSettings()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("GetPluginSettings"), argumentList);
}
inline QDBusPendingReply<bool> IsDocked(const QString &in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("IsDocked"), argumentList);
}
inline QDBusPendingReply<bool> IsOnDock(const QString &in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("IsOnDock"), argumentList);
}
inline QDBusPendingReply<> MergePluginSettings(const QString &in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("MergePluginSettings"), argumentList);
}
inline void MergePluginSettingsQueued(const QString &in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("MergePluginSettings"), argumentList);
}
inline QDBusPendingReply<> MoveEntry(int in0, int in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
return asyncCallWithArgumentList(QStringLiteral("MoveEntry"), argumentList);
}
inline void MoveEntryQueued(int in0, int in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
CallQueued(QStringLiteral("MoveEntry"), argumentList);
}
inline void MoveWindowQueued(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("MoveWindow"), argumentList);
}
inline QDBusPendingReply<QString> QueryWindowIdentifyMethod(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("QueryWindowIdentifyMethod"), argumentList);
}
inline QDBusPendingReply<> RemovePluginSettings(const QString &in0, const QStringList &in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
return asyncCallWithArgumentList(QStringLiteral("RemovePluginSettings"), argumentList);
}
inline void RemovePluginSettingsQueued(const QString &in0, const QStringList &in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
CallQueued(QStringLiteral("RemovePluginSettings"), argumentList);
}
inline QDBusPendingReply<bool> RequestDock(const QString &in0, int in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
return asyncCallWithArgumentList(QStringLiteral("RequestDock"), argumentList);
}
inline QDBusPendingReply<bool> RequestUndock(const QString &in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("RequestUndock"), argumentList);
}
inline void SetShowRecent(bool in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("SetShowRecent"), argumentList);
}
inline QDBusPendingReply<> SetFrontendWindowRect(int in0, int in1, uint in2, uint in3)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3);
return asyncCallWithArgumentList(QStringLiteral("SetFrontendWindowRect"), argumentList);
}
inline void SetFrontendWindowRectQueued(int in0, int in1, uint in2, uint in3)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3);
CallQueued(QStringLiteral("SetFrontendWindowRect"), argumentList);
}
inline QDBusPendingReply<> SetPluginSettings(const QString &in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("SetPluginSettings"), argumentList);
}
inline void SetPluginSettingsQueued(const QString &in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("SetPluginSettings"), argumentList);
}
Q_SIGNALS: // SIGNALS
void DockAppSettingsSynced();
void EntryAdded(const QDBusObjectPath &in0, int in1);
void EntryRemoved(const QString &in0);
void PluginSettingsSynced();
void ServiceRestarted();
// begin property changed signals
void DisplayModeChanged(int value) const;
void DockedAppsChanged(const QStringList &value) const;
void EntriesChanged(const QList<QDBusObjectPath> &value) const;
void FrontendWindowRectChanged(DockRect value) const;
void HideModeChanged(int value) const;
void HideStateChanged(int value) const;
void HideTimeoutChanged(uint value) const;
void IconSizeChanged(uint value) const;
void OpacityChanged(double value) const;
void PositionChanged(int value) const;
void ShowTimeoutChanged(uint value) const;
void WindowSizeChanged(uint value) const;
void WindowSizeEfficientChanged(uint value) const;
void WindowSizeFashionChanged(uint value) const;
void showRecentChanged(bool) const;
void ShowMultiWindowChanged(bool) const;
public Q_SLOTS:
void CallQueued(const QString &callName, const QList<QVariant> &args);
private Q_SLOTS:
void onPendingCallFinished(QDBusPendingCallWatcher *w);
void onPropertyChanged(const QDBusMessage& msg);
private:
DockPrivate *d_ptr;
WM *m_wm;
};
namespace org {
namespace deepin {
namespace dde {
namespace daemon {
typedef ::Dde_Dock DdeDock;
}
}
}
}
#endif // DOCK_INTERFACE

View File

@ -1,295 +0,0 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* 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/>.
*/
#include "entryinterface.h"
/*
* Implementation of interface class __Entry
*/
void registerWindowListMetaType()
{
qRegisterMetaType<WindowList>();
qDBusRegisterMetaType<WindowList>();
}
void registerWindowInfoMapMetaType()
{
registerWindowInfoMetaType();
qRegisterMetaType<WindowInfoMap>("WindowInfoMap");
qDBusRegisterMetaType<WindowInfoMap>();
}
void registerWindowInfoMetaType()
{
qRegisterMetaType<WindowInfo>("WindowInfo");
qDBusRegisterMetaType<WindowInfo>();
}
QDebug operator<<(QDebug argument, const WindowInfo &info)
{
argument << '(' << info.title << ',' << info.attention << info.uuid << ')';
return argument;
}
QDBusArgument &operator<<(QDBusArgument &argument, const WindowInfo &info)
{
argument.beginStructure();
argument << info.title << info.attention << info.uuid;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, WindowInfo &info)
{
argument.beginStructure();
argument >> info.title >> info.attention >> info.uuid;
argument.endStructure();
return argument;
}
bool WindowInfo::operator==(const WindowInfo &rhs) const
{
return (attention == rhs.attention &&
title == rhs.title &&
uuid == rhs.uuid);
}
class EntryPrivate
{
public:
EntryPrivate()
: CurrentWindow(0)
, IsActive(false)
, IsDocked(false)
, mode(0)
{}
// begin member variables
uint CurrentWindow;
QString DesktopFile;
QString Icon;
QString Id;
bool IsActive;
bool IsDocked;
QString Menu;
QString Name;
WindowInfoMap WindowInfos;
int mode;
public:
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
QMap<QString, QList<QVariant>> m_waittingCalls;
};
Dock_Entry::Dock_Entry(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
, d_ptr(new EntryPrivate)
{
QDBusConnection::sessionBus().connect(this->service(), this->path(),
"org.freedesktop.DBus.Properties",
"PropertiesChanged","sa{sv}as",
this,
SLOT(onPropertyChanged(const QDBusMessage &)));
if (QMetaType::type("WindowList") == QMetaType::UnknownType)
registerWindowListMetaType();
if (QMetaType::type("WindowInfoMap") == QMetaType::UnknownType)
registerWindowInfoMapMetaType();
}
Dock_Entry::~Dock_Entry()
{
qDeleteAll(d_ptr->m_processingCalls.values());
delete d_ptr;
}
void Dock_Entry::onPropertyChanged(const QString &propName, const QVariant &value)
{
if (propName == QStringLiteral("CurrentWindow")) {
const uint &CurrentWindow = qvariant_cast<uint>(value);
if (d_ptr->CurrentWindow != CurrentWindow) {
d_ptr->CurrentWindow = CurrentWindow;
Q_EMIT CurrentWindowChanged(d_ptr->CurrentWindow);
}
return;
}
if (propName == QStringLiteral("DesktopFile")) {
const QString &DesktopFile = qvariant_cast<QString>(value);
if (d_ptr->DesktopFile != DesktopFile) {
d_ptr->DesktopFile = DesktopFile;
Q_EMIT DesktopFileChanged(d_ptr->DesktopFile);
}
return;
}
if (propName == QStringLiteral("Icon")) {
const QString &Icon = qvariant_cast<QString>(value);
if (d_ptr->Icon != Icon)
{
d_ptr->Icon = Icon;
Q_EMIT IconChanged(d_ptr->Icon);
}
return;
}
if (propName == QStringLiteral("IsActive")) {
const bool &IsActive = qvariant_cast<bool>(value);
if (d_ptr->IsActive != IsActive) {
d_ptr->IsActive = IsActive;
Q_EMIT IsActiveChanged(d_ptr->IsActive);
}
return;
}
if (propName == QStringLiteral("IsDocked")) {
const bool &IsDocked = qvariant_cast<bool>(value);
if (d_ptr->IsDocked != IsDocked) {
d_ptr->IsDocked = IsDocked;
Q_EMIT IsDockedChanged(d_ptr->IsDocked);
}
return;
}
if (propName == QStringLiteral("Menu")) {
const QString &Menu = qvariant_cast<QString>(value);
if (d_ptr->Menu != Menu) {
d_ptr->Menu = Menu;
Q_EMIT MenuChanged(d_ptr->Menu);
}
return;
}
if (propName == QStringLiteral("Name")) {
const QString &Name = qvariant_cast<QString>(value);
if (d_ptr->Name != Name) {
d_ptr->Name = Name;
Q_EMIT NameChanged(d_ptr->Name);
}
return;
}
if (propName == QStringLiteral("WindowInfos")) {
const WindowInfoMap &WindowInfos = qvariant_cast<WindowInfoMap>(value);
if (d_ptr->WindowInfos != WindowInfos) {
d_ptr->WindowInfos = WindowInfos;
Q_EMIT WindowInfosChanged(d_ptr->WindowInfos);
}
return;
}
if (propName == QStringLiteral("Mode")) {
const int mode = qvariant_cast<int>(value);
if (d_ptr->mode != mode) {
d_ptr->mode = mode;
Q_EMIT ModeChanged(d_ptr->mode);
}
}
qWarning() << "property not handle: " << propName;
return;
}
uint Dock_Entry::currentWindow()
{
return qvariant_cast<uint>(property("CurrentWindow"));
}
QString Dock_Entry::desktopFile()
{
return qvariant_cast<QString>(property("DesktopFile"));
}
QString Dock_Entry::icon()
{
return qvariant_cast<QString>(property("Icon"));
}
QString Dock_Entry::id()
{
return qvariant_cast<QString>(property("Id"));
}
bool Dock_Entry::isActive()
{
return qvariant_cast<bool>(property("IsActive"));
}
bool Dock_Entry::isDocked()
{
return qvariant_cast<bool>(property("IsDocked"));
}
int Dock_Entry::mode() const
{
return qvariant_cast<int>(property("Mode"));
}
QString Dock_Entry::menu()
{
return qvariant_cast<QString>(property("Menu"));
}
QString Dock_Entry::name()
{
return qvariant_cast<QString>(property("Name"));
}
WindowInfoMap Dock_Entry::windowInfos()
{
return qvariant_cast<WindowInfoMap>(property("WindowInfos"));
}
void Dock_Entry::CallQueued(const QString &callName, const QList<QVariant> &args)
{
if (d_ptr->m_waittingCalls.contains(callName)) {
d_ptr->m_waittingCalls[callName] = args;
return;
}
if (d_ptr->m_processingCalls.contains(callName)) {
d_ptr->m_waittingCalls.insert(callName, args);
} else {
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
connect(watcher, &QDBusPendingCallWatcher::finished, this, &Dock_Entry::onPendingCallFinished);
d_ptr->m_processingCalls.insert(callName, watcher);
}
}
void Dock_Entry::onPendingCallFinished(QDBusPendingCallWatcher *w)
{
w->deleteLater();
const auto callName = d_ptr->m_processingCalls.key(w);
Q_ASSERT(!callName.isEmpty());
if (callName.isEmpty())
return;
d_ptr->m_processingCalls.remove(callName);
if (!d_ptr->m_waittingCalls.contains(callName))
return;
const auto args = d_ptr->m_waittingCalls.take(callName);
CallQueued(callName, args);
}

View File

@ -1,282 +0,0 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* 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/>.
*/
#ifndef DOCK_ENTRY_H
#define DOCK_ENTRY_H
#define WINDOWLIST_H
#define WINDOWINFOLIST_H
#include <QObject>
#include <QByteArray>
#include <QList>
#include <QMap>
#include <QString>
#include <QStringList>
#include <QVariant>
#include <DDBusExtendedAbstractInterface>
#include <QtDBus>
typedef QList<quint32> WindowList;
void registerWindowListMetaType();
class WindowInfo
{
public:
friend QDebug operator<<(QDebug argument, const WindowInfo &info);
friend QDBusArgument &operator<<(QDBusArgument &argument, const WindowInfo &info);
friend const QDBusArgument &operator>>(const QDBusArgument &argument, WindowInfo &info);
bool operator==(const WindowInfo &rhs) const;
public:
bool attention;
QString title;
QString uuid;
};
Q_DECLARE_METATYPE(WindowInfo)
typedef QMap<quint32, WindowInfo> WindowInfoMap;
Q_DECLARE_METATYPE(WindowInfoMap)
void registerWindowInfoMetaType();
void registerWindowInfoMapMetaType();
/*
* Proxy class for interface org.deepin.dde.daemon.Dock1.Entry
*/
class EntryPrivate;
class Dock_Entry : public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{ return "org.deepin.dde.daemon.Dock1.Entry"; }
public:
explicit Dock_Entry(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
~Dock_Entry();
Q_PROPERTY(uint CurrentWindow READ currentWindow NOTIFY CurrentWindowChanged)
uint currentWindow();
Q_PROPERTY(QString DesktopFile READ desktopFile NOTIFY DesktopFileChanged)
QString desktopFile();
Q_PROPERTY(QString Icon READ icon NOTIFY IconChanged)
QString icon();
Q_PROPERTY(QString Id READ id)
QString id();
Q_PROPERTY(bool IsActive READ isActive NOTIFY IsActiveChanged)
bool isActive();
Q_PROPERTY(bool IsDocked READ isDocked NOTIFY IsDockedChanged)
bool isDocked();
Q_PROPERTY(QString Menu READ menu NOTIFY MenuChanged)
QString menu();
Q_PROPERTY(QString Name READ name NOTIFY NameChanged)
QString name();
Q_PROPERTY(WindowInfoMap WindowInfos READ windowInfos NOTIFY WindowInfosChanged)
WindowInfoMap windowInfos();
Q_PROPERTY(int Mode READ mode NOTIFY ModeChanged)
int mode() const;
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> Activate(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("Activate"), argumentList);
}
inline void ActivateQueued(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("Activate"), argumentList);
}
inline QDBusPendingReply<> Check()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("Check"), argumentList);
}
inline void CheckQueued()
{
QList<QVariant> argumentList;
CallQueued(QStringLiteral("Check"), argumentList);
}
inline QDBusPendingReply<> ForceQuit()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("ForceQuit"), argumentList);
}
inline QDBusPendingReply<> ActiveWindow(quint32 in0)
{
QList<QVariant> argumentList;
argumentList << in0;
return asyncCallWithArgumentList(QStringLiteral("ActiveWindow"), argumentList);
}
inline void ForceQuitQueued()
{
QList<QVariant> argumentList;
CallQueued(QStringLiteral("ForceQuit"), argumentList);
}
inline QDBusPendingReply<WindowList> GetAllowedCloseWindows()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("GetAllowedCloseWindows"), argumentList);
}
inline QDBusPendingReply<> HandleDragDrop(uint in0, const QStringList &in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
return asyncCallWithArgumentList(QStringLiteral("HandleDragDrop"), argumentList);
}
inline void HandleDragDropQueued(uint in0, const QStringList &in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
CallQueued(QStringLiteral("HandleDragDrop"), argumentList);
}
inline QDBusPendingReply<> HandleMenuItem(uint in0, const QString &in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
return asyncCallWithArgumentList(QStringLiteral("HandleMenuItem"), argumentList);
}
inline void HandleMenuItemQueued(uint in0, const QString &in1)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1);
CallQueued(QStringLiteral("HandleMenuItem"), argumentList);
}
inline QDBusPendingReply<> NewInstance(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
return asyncCallWithArgumentList(QStringLiteral("NewInstance"), argumentList);
}
inline void NewInstanceQueued(uint in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("NewInstance"), argumentList);
}
inline QDBusPendingReply<> PresentWindows()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("PresentWindows"), argumentList);
}
inline void PresentWindowsQueued()
{
QList<QVariant> argumentList;
CallQueued(QStringLiteral("PresentWindows"), argumentList);
}
inline QDBusPendingReply<> RequestDock()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("RequestDock"), argumentList);
}
inline void RequestDockQueued()
{
QList<QVariant> argumentList;
CallQueued(QStringLiteral("RequestDock"), argumentList);
}
inline QDBusPendingReply<> RequestUndock()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("RequestUndock"), argumentList);
}
inline void RequestUndockQueued()
{
QList<QVariant> argumentList;
CallQueued(QStringLiteral("RequestUndock"), argumentList);
}
Q_SIGNALS: // SIGNALS
// begin property changed signals
void IsActiveChanged(bool value) const;
void IsDockedChanged(bool value) const;
void MenuChanged(const QString &value) const;
void IconChanged(const QString &value) const;
void NameChanged(const QString &value) const;
void DesktopFileChanged(const QString &value) const;
void CurrentWindowChanged(uint32_t value) const;
void WindowInfosChanged(WindowInfoMap value) const;
void ModeChanged(int value) const;
private:
QVariant asyncProperty(const QString &propertyName);
public Q_SLOTS:
void CallQueued(const QString &callName, const QList<QVariant> &args);
private Q_SLOTS:
void onPendingCallFinished(QDBusPendingCallWatcher *w);
void onPropertyChanged(const QString &propName, const QVariant &value);
private:
EntryPrivate *d_ptr;
};
namespace org {
namespace deepin {
namespace dde {
namespace daemon {
namespace dock {
typedef ::Dock_Entry DockEntry;
}
}
}
}
}
#endif // DOCK_ENTRY_H

View File

@ -1,31 +0,0 @@
<interface name="org.deepin.dde.daemon.Dock1">
<method name="ActivateWindow">
<arg type="u" direction="in"></arg>
</method>
<method name="CloseWindow">
<arg type="u" direction="in"></arg>
</method>
<method name="GetEntryIDs">
<arg type="as" direction="out"></arg>
</method>
<method name="ReorderEntries">
<arg type="as" direction="in"></arg>
</method>
<method name="SetFrontendWindow">
<arg type="u" direction="in"></arg>
</method>
<signal name="ServiceRestarted"></signal>
<signal name="EntryAdded">
<arg type="o"></arg>
</signal>
<signal name="EntryRemoved">
<arg type="s"></arg>
</signal>
<property name="Entries" type="ao" access="read"></property>
<property name="HideMode" type="i" access="readwrite"></property>
<property name="DisplayMode" type="i" access="readwrite"></property>
<property name="Position" type="i" access="readwrite"></property>
<property name="ActiveWindow" type="u" access="read"></property>
<property name="HideState" type="i" access="read"></property>
</interface>

View File

@ -18,7 +18,6 @@ public:
friend const QDBusArgument &operator>>(const QDBusArgument &arg, DockRect &rect);
friend QDBusArgument &operator<<(QDBusArgument &arg, const DockRect &rect);
private:
int x;
int y;
uint w;

View File

@ -0,0 +1,166 @@
<interface name="com.deepin.wm">
<property access="readwrite" type="b" name="compositingEnabled"/>
<property access="read" type="b" name="compositingPossible"/>
<property access="read" type="b" name="compositingAllowSwitch"/>
<property access="readwrite" type="b" name="zoneEnabled"/>
<property access="readwrite" type="s" name="cursorTheme"/>
<property access="readwrite" type="i" name="cursorSize"/>
<method name="SwitchApplication">
<arg direction="in" type="b" name="backward"/>
</method>
<method name="TileActiveWindow">
<arg direction="in" type="u" name="side"/>
</method>
<method name="BeginToMoveActiveWindow"/>
<method name="ToggleActiveWindowMaximize"/>
<method name="MinimizeActiveWindow"/>
<method name="ShowWorkspace"/>
<method name="ShowWindow"/>
<method name="ShowAllWindow"/>
<method name="PerformAction">
<arg direction="in" type="i" name="type"/>
</method>
<method name="PreviewWindow">
<arg direction="in" type="u" name="xid"/>
</method>
<method name="CancelPreviewWindow"/>
<method name="GetCurrentWorkspaceBackground">
<arg direction="out" type="s" name="result"/>
</method>
<method name="SetCurrentWorkspaceBackground">
<arg direction="in" type="s" name="uri"/>
</method>
<method name="GetWorkspaceBackground">
<arg direction="in" type="i" name="index"/>
<arg direction="out" type="s" name="result"/>
</method>
<method name="SetWorkspaceBackground">
<arg direction="in" type="i" name="index"/>
<arg direction="in" type="s" name="uri"/>
</method>
<method name="SetTransientBackground">
<arg direction="in" type="s"/>
</method>
<method name="GetCurrentWorkspaceBackgroundForMonitor">
<arg direction="in" type="s" name="strMonitorName"/>
<arg direction="out" type="s" name="result"/>
</method>
<method name="SetCurrentWorkspaceBackgroundForMonitor">
<arg direction="in" type="s" name="uri"/>
<arg direction="in" type="s" name="strMonitorName"/>
</method>
<method name="GetWorkspaceBackgroundForMonitor">
<arg direction="in" type="i" name="index"/>
<arg direction="in" type="s" name="strMonitorName"/>
<arg direction="out" type="s" name="result"/>
</method>
<method name="SetWorkspaceBackgroundForMonitor">
<arg direction="in" type="i" name="index"/>
<arg direction="in" type="s" name="strMonitorName"/>
<arg direction="in" type="s" name="uri"/>
</method>
<method name="SetTransientBackgroundForMonitor">
<arg direction="in" type="s" name="uri"/>
<arg direction="in" type="s" name="strMonitorName"/>
</method>
<method name="GetCurrentWorkspace">
<arg direction="out" type="i" name="index"/>
</method>
<method name="WorkspaceCount">
<arg direction="out" type="i" name="count"/>
</method>
<method name="SetCurrentWorkspace">
<arg direction="in" type="i" name="index"/>
</method>
<method name="PreviousWorkspace"/>
<method name="NextWorkspace"/>
<method name="GetAllAccels">
<arg direction="out" type="s" name="data"/>
</method>
<method name="GetAccel">
<arg direction="in" type="s" name="id"/>
<arg direction="out" type="as" name="data"/>
</method>
<method name="GetDefaultAccel">
<arg direction="in" type="s" name="id"/>
<arg direction="out" type="as" name="data"/>
</method>
<method name="SetAccel">
<arg direction="in" type="s" name="data"/>
<arg direction="out" type="b" name="result"/>
</method>
<method name="RemoveAccel">
<arg direction="in" type="s" name="id"/>\
</method>
<method name="SetDecorationTheme">
<arg direction="in" type="s" name="themeType"/>
<arg direction="in" type="s" name="themeName"/>
</method>
<method name="SetDecorationDeepinTheme">
<arg direction="in" type="s" name="deepinThemeName"/>
</method>
<signal name="WorkspaceBackgroundChanged">
<arg type="i" name="index"/>
<arg type="s" name="newUri"/>
</signal>
<signal name="WorkspaceBackgroundChangedForMonitor">
<arg type="i" name="index"/>
<arg type="s" name="strMonitorName"/>
<arg type="s" name="uri"/>
</signal>
<signal name="compositingEnabledChanged">
<arg type="b" name="enabled"/>
</signal>
<signal name="wmCompositingEnabledChanged">
<arg type="b" name="enabled"/>
</signal>
<signal name="workspaceCountChanged">
<arg type="i" name="count"/>
</signal>
<signal name="BeginToMoveActiveWindowChanged"/>
<signal name="SwitchApplicationChanged">
<arg type="b" name="backward"/>
</signal>
<signal name="TileActiveWindowChanged">
<arg type="i" name="side"/>
</signal>
<signal name="ToggleActiveWindowMaximizeChanged"/>
<signal name="ShowAllWindowChanged"/>
<signal name="ShowWindowChanged"/>
<signal name="ShowWorkspaceChanged"/>
<signal name="ResumeCompositorChanged">
<arg type="i" name="reason"/>
</signal>
<signal name="SuspendCompositorChanged">
<arg type="i" name="reason"/>
</signal>
<method name="ChangeCurrentWorkspaceBackground">
<arg direction="in" type="s" name="uri"/>
</method>
<method name="SwitchToWorkspace">
<arg direction="in" type="b" name="backward"/>
</method>
<method name="PresentWindows">
<arg direction="in" type="au" name="xids"/>
<annotation value="QList&lt;uint&gt;" name="org.qtproject.QtDBus.QtTypeName.In0"/>
</method>
<method name="EnableZoneDetected">
<arg direction="in" type="b" name="enabled"/>
</method>
<signal name="WorkspaceSwitched">
<arg type="i" name="from"/>
<arg type="i" name="to"/>
</signal>
<method name="GetMultiTaskingStatus">
<arg direction="out" type="b" name="isActive"/>
</method>
<method name="SetMultiTaskingStatus">
<arg direction="in" type="b" name="isActive"/>
</method>
<method name="GetIsShowDesktop">
<arg direction="out" type="b" name="isShowDesktop"/>
</method>
<method name="SetShowDesktop">
<arg direction="in" type="b" name="isShowDesktop"/>
</method>
</interface>

View File

@ -0,0 +1,12 @@
<interface name="org.deepin.dde.WMSwitcher1">
<method name="AllowSwitch">
<arg direction="out" type="b" name="outArg0"/>
</method>
<method name="CurrentWM">
<arg direction="out" type="s" name="outArg0"/>
</method>
<method name="RequestSwitchWM"/>
<signal name="WMChanged">
<arg type="s" name="wmName"/>
</signal>
</interface>

View File

@ -1,100 +0,0 @@
<interface name="org.deepin.dde.daemon.Dock1">
<method name="ActivateWindow">
<arg type="u" direction="in"/>
</method>
<method name="CancelPreviewWindow"/>
<method name="CloseWindow">
<arg type="u" direction="in"/>
</method>
<method name="GetDockedAppsDesktopFiles">
<arg type="as" direction="out"/>
</method>
<method name="GetEntryIDs">
<arg type="as" direction="out"/>
</method>
<method name="GetPluginSettings">
<arg type="s" direction="out"/>
</method>
<method name="IsDocked">
<arg type="s" direction="in"/>
<arg type="b" direction="out"/>
</method>
<method name="IsOnDock">
<arg type="s" direction="in"/>
<arg type="b" direction="out"/>
</method>
<method name="MakeWindowAbove">
<arg type="u" direction="in"/>
</method>
<method name="MaximizeWindow">
<arg type="u" direction="in"/>
</method>
<method name="MinimizeWindow">
<arg type="u" direction="in"/>
</method>
<method name="MoveEntry">
<arg type="i" direction="in"/>
<arg type="i" direction="in"/>
</method>
<method name="MoveWindow">
<arg type="u" direction="in"/>
</method>
<method name="PreviewWindow">
<arg type="u" direction="in"/>
</method>
<method name="QueryWindowIdentifyMethod">
<arg type="u" direction="in"/>
<arg type="s" direction="out"/>
</method>
<method name="RemovePluginSettings">
<arg type="s" direction="in"/>
<arg type="as" direction="in"/>
</method>
<method name="RequestDock">
<arg type="s" direction="in"/>
<arg type="i" direction="in"/>
<arg type="b" direction="out"/>
</method>
<method name="RequestUndock">
<arg type="s" direction="in"/>
<arg type="b" direction="out"/>
</method>
<method name="SetFrontendWindowRect">
<arg type="i" direction="in"/>
<arg type="i" direction="in"/>
<arg type="u" direction="in"/>
<arg type="u" direction="in"/>
</method>
<method name="SetPluginSettings">
<arg type="s" direction="in"/>
</method>
<method name="MergePluginSettings">
<arg type="s" direction="in"/>
</method>
<signal name="ServiceRestarted"/>
<signal name="EntryAdded">
<arg type="o"/>
<arg type="i"/>
</signal>
<signal name="EntryRemoved">
<arg type="s"/>
</signal>
<signal name="PluginSettingsSynced"/>
<signal name="DockAppSettingsSynced"/>
<property name="Entries" type="ao" access="read"/>
<property name="HideMode" type="i" access="readwrite"/>
<property name="DisplayMode" type="i" access="readwrite"/>
<property name="Position" type="i" access="readwrite"/>
<property name="IconSize" type="u" access="readwrite"/>
<property name="WindowSize" type="u" access="readwrite"/>
<property name="WindowSizeEfficient" type="u" access="readwrite"/>
<property name="WindowSizeFashion" type="u" access="readwrite"/>
<property name="ShowTimeout" type="u" access="readwrite"/>
<property name="HideTimeout" type="u" access="readwrite"/>
<property name="DockedApps" type="as" access="read"/>
<property name="HideState" type="i" access="read"/>
<property name="FrontendWindowRect" type="(iiuu)" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="DockRect"/>
</property>
<property name="Opacity" type="d" access="readwrite"/>
</interface>

View File

@ -0,0 +1,146 @@
<interface name="org.deepin.dde.KWayland1.PlasmaWindow">
<signal name="ActiveChanged"/>
<signal name="AppIdChanged"/>
<signal name="CloseableChanged"/>
<signal name="DemandsAttentionChanged"/>
<signal name="FullscreenableChanged"/>
<signal name="FullscreenChanged"/>
<signal name="GeometryChanged"/>
<signal name="IconChanged"/>
<signal name="KeepAboveChanged"/>
<signal name="KeepBelowChanged"/>
<signal name="MaximizeableChanged"/>
<signal name="MaximizedChanged"/>
<signal name="MinimizeableChanged"/>
<signal name="MinimizedChanged"/>
<signal name="MovableChanged"/>
<signal name="OnAllDesktopsChanged"/>
<signal name="ParentWindowChanged"/>
<signal name="PlasmaVirtualDesktopEntered">
<arg name="id" type="s" direction="out"/>
</signal>
<signal name="PlasmaVirtualDesktopLeft">
<arg name="id" type="s" direction="out"/>
</signal>
<signal name="ResizableChanged"/>
<signal name="ShadeableChanged"/>
<signal name="ShadedChanged"/>
<signal name="SkipSwitcherChanged"/>
<signal name="SkipTaskbarChanged"/>
<signal name="TitleChanged"/>
<signal name="Unmapped"/>
<signal name="VirtualDesktopChangeableChanged"/>
<signal name="VirtualDesktopChanged"/>
<method name="AppId">
<arg type="s" direction="out"/>
</method>
<method name="Destroy"/>
<method name="Geometry">
<arg type="(iiii)" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="DockRect"/>
</method>
<method name="Icon">
<arg type="s" direction="out"/>
</method>
<method name="InternalId">
<arg type="u" direction="out"/>
</method>
<method name="IsActive">
<arg type="b" direction="out"/>
</method>
<method name="IsCloseable">
<arg type="b" direction="out"/>
</method>
<method name="IsDemandingAttention">
<arg type="b" direction="out"/>
</method>
<method name="IsFullscreen">
<arg type="b" direction="out"/>
</method>
<method name="IsFullscreenable">
<arg type="b" direction="out"/>
</method>
<method name="IsKeepAbove">
<arg type="b" direction="out"/>
</method>
<method name="IsKeepBelow">
<arg type="b" direction="out"/>
</method>
<method name="IsMaximizeable">
<arg type="b" direction="out"/>
</method>
<method name="IsMaximized">
<arg type="b" direction="out"/>
</method>
<method name="IsMinimizeable">
<arg type="b" direction="out"/>
</method>
<method name="IsMinimized">
<arg type="b" direction="out"/>
</method>
<method name="IsMovable">
<arg type="b" direction="out"/>
</method>
<method name="IsOnAllDesktops">
<arg type="b" direction="out"/>
</method>
<method name="IsResizable">
<arg type="b" direction="out"/>
</method>
<method name="IsShadeable">
<arg type="b" direction="out"/>
</method>
<method name="IsShaded">
<arg type="b" direction="out"/>
</method>
<method name="IsValid">
<arg type="b" direction="out"/>
</method>
<method name="IsVirtualDesktopChangeable">
<arg type="b" direction="out"/>
</method>
<method name="Pid">
<arg type="u" direction="out"/>
</method>
<method name="PlasmaVirtualDesktops">
<arg type="as" direction="out"/>
</method>
<method name="Release"/>
<method name="RequestActivate"/>
<method name="RequestClose"/>
<method name="RequestEnterNewVirtualDesktop"/>
<method name="RequestEnterVirtualDesktop">
<arg name="id" type="s" direction="in"/>
</method>
<method name="RequestLeaveVirtualDesktop">
<arg name="id" type="s" direction="in"/>
</method>
<method name="RequestMove"/>
<method name="RequestResize"/>
<method name="RequestToggleKeepAbove"/>
<method name="RequestToggleKeepBelow"/>
<method name="RequestToggleMaximized"/>
<method name="RequestToggleMinimized"/>
<method name="RequestToggleShaded"/>
<method name="RequestVirtualDesktop">
<arg name="desktop" type="u" direction="in"/>
</method>
<method name="SkipSwitcher">
<arg type="b" direction="out"/>
</method>
<method name="SkipTaskbar">
<arg type="b" direction="out"/>
</method>
<method name="Title">
<arg type="s" direction="out"/>
</method>
<method name="VirtualDesktop">
<arg type="u" direction="out"/>
</method>
<method name="WindowId">
<arg type="u" direction="out"/>
</method>
<method name="uuid">
<arg type="ay" direction="out"/>
</method>
</interface>

View File

@ -0,0 +1,31 @@
<interface name="org.deepin.dde.KWayland1.WindowManager">
<signal name="InterfaceAboutToBeReleased"/>
<signal name="InterfaceAboutToBeDestroyed"/>
<signal name="ShowingDesktopChanged">
<arg type="b" direction="out"/>
</signal>
<signal name="WindowCreated">
<arg name="dbus" type="s" direction="out"/>
</signal>
<signal name="WindowRemove">
<arg name="dbus" type="s" direction="out"/>
</signal>
<signal name="ActiveWindowChanged"/>
<method name="IsValid">
<arg type="b" direction="out"/>
</method>
<method name="IsShowingDesktop">
<arg type="b" direction="out"/>
</method>
<method name="SetShowingDesktop">
<arg name="show" type="b" direction="in"/>
</method>
<method name="ShowDesktop"/>
<method name="HideDesktop"/>
<method name="Windows">
<arg type="av" direction="out"/>
</method>
<method name="ActiveWindow">
<arg type="u" direction="out"/>
</method>
</interface>

View File

@ -4,6 +4,8 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "appitem.h"
#include "docksettings.h"
#include "taskmanager/windowinfobase.h"
#include "themeappicon.h"
#include "xcb_misc.h"
#include "appswingeffectbuilder.h"
@ -24,8 +26,12 @@
#include <QGSettings>
#include <DGuiApplicationHelper>
#include <DPlatformTheme>
#include <DConfig>
#include <cstdint>
#include <sys/types.h>
DGUI_USE_NAMESPACE
DCORE_USE_NAMESPACE
@ -33,13 +39,13 @@ DCORE_USE_NAMESPACE
QPoint AppItem::MousePressPos;
AppItem::AppItem(DockInter *dockInter, const QGSettings *appSettings, const QGSettings *activeAppSettings, const QGSettings *dockedAppSettings, const QDBusObjectPath &entry, QWidget *parent)
AppItem::AppItem(const QGSettings *appSettings, const QGSettings *activeAppSettings, const QGSettings *dockedAppSettings, const Entry *entry, QWidget *parent)
: DockItem(parent)
, m_appSettings(appSettings)
, m_activeAppSettings(activeAppSettings)
, m_dockedAppSettings(dockedAppSettings)
, m_itemEntry(const_cast<Entry*>(entry))
, m_appPreviewTips(nullptr)
, m_itemEntryInter(new DockEntryInter(dockServiceName(), entry.path(), QDBusConnection::sessionBus(), this))
, m_swingEffectView(nullptr)
, m_itemAnimation(nullptr)
, m_wmHelper(DWindowManagerHelper::instance())
@ -47,25 +53,32 @@ AppItem::AppItem(DockInter *dockInter, const QGSettings *appSettings, const QGSe
, m_retryTimes(0)
, m_iconValid(true)
, m_lastclickTimes(0)
, m_showMultiWindow(DockSettings::instance()->showMultiWindow())
, m_appIcon(QPixmap())
, m_activeColor(DGuiApplicationHelper::instance()->systemTheme()->activeColor())
, m_updateIconGeometryTimer(new QTimer(this))
, m_retryObtainIconTimer(new QTimer(this))
, m_refershIconTimer(new QTimer(this))
, m_themeType(DGuiApplicationHelper::instance()->themeType())
, m_createMSecs(QDateTime::currentMSecsSinceEpoch())
, m_screenSpliter(ScreenSpliterFactory::createScreenSpliter(this, m_itemEntryInter))
, m_dockInter(dockInter)
, m_screenSpliter(ScreenSpliterFactory::createScreenSpliter(this))
{
QHBoxLayout *centralLayout = new QHBoxLayout;
centralLayout->setMargin(0);
centralLayout->setSpacing(0);
setObjectName(m_itemEntryInter->name());
setAcceptDrops(true);
setLayout(centralLayout);
m_id = m_itemEntryInter->id();
m_active = m_itemEntryInter->isActive();
m_id = m_itemEntry->getId();
m_active = m_itemEntry->getIsActive();
m_name = m_itemEntry->getName();
m_icon = m_itemEntry->getIcon();
m_mode = m_itemEntry->mode();
m_isDocked = m_itemEntry->getIsDocked();
m_menu = m_itemEntry->getMenu();
setObjectName(m_name);
m_updateIconGeometryTimer->setInterval(500);
m_updateIconGeometryTimer->setSingleShot(true);
@ -76,17 +89,32 @@ AppItem::AppItem(DockInter *dockInter, const QGSettings *appSettings, const QGSe
m_refershIconTimer->setInterval(1000);
m_refershIconTimer->setSingleShot(false);
connect(m_itemEntryInter, &DockEntryInter::IsActiveChanged, this, &AppItem::activeChanged);
connect(m_itemEntryInter, &DockEntryInter::IsActiveChanged, this, static_cast<void (AppItem::*)()>(&AppItem::update));
connect(m_itemEntryInter, &DockEntryInter::WindowInfosChanged, this, &AppItem::updateWindowInfos, Qt::QueuedConnection);
connect(m_itemEntryInter, &DockEntryInter::IconChanged, this, &AppItem::refreshIcon);
connect(m_itemEntryInter, &DockEntryInter::ModeChanged, this, &AppItem::modeChanged);
connect(m_itemEntry, &Entry::isActiveChanged, this, &AppItem::activeChanged);
connect(m_itemEntry, &Entry::isActiveChanged, this, static_cast<void (AppItem::*)()>(&AppItem::update));
connect(m_itemEntry, &Entry::windowInfosChanged, this, &AppItem::updateWindowInfos, Qt::QueuedConnection);
connect(m_itemEntry, &Entry::iconChanged, this, [=](QString icon) {
if (!icon.isEmpty() && icon != m_icon)
m_icon = icon;
});
connect(m_itemEntry, &Entry::iconChanged, this, &AppItem::refreshIcon);
connect(m_itemEntry, &Entry::modeChanged, this, [=] (int32_t mode) { m_mode = mode; Q_EMIT modeChanged(m_mode);});
connect(m_updateIconGeometryTimer, &QTimer::timeout, this, &AppItem::updateWindowIconGeometries, Qt::QueuedConnection);
connect(m_retryObtainIconTimer, &QTimer::timeout, this, &AppItem::refreshIcon, Qt::QueuedConnection);
connect(DockSettings::instance(), &DockSettings::showMultiWindowChanged, this, [=] (bool show) {
m_showMultiWindow = show;
});
connect(m_itemEntry, &Entry::nameChanged, this, [=](const QString& name){ m_name = name; });
connect(m_itemEntry, &Entry::desktopFileChanged, this, [=](const QString& desktopfile){ m_desktopfile = desktopfile; });
connect(m_itemEntry, &Entry::isDockedChanged, this, [=](bool docked){ m_isDocked = docked; });
connect(m_itemEntry, &Entry::menuChanged, this, [=](const QString& menu){ m_menu = menu; });
connect(m_itemEntry, &Entry::currentWindowChanged, this, [=](uint32_t currentWindow){
m_currentWindow = currentWindow;
Q_EMIT onCurrentWindowChanged(m_currentWindow);
});
connect(this, &AppItem::requestUpdateEntryGeometries, this, &AppItem::updateWindowIconGeometries);
updateWindowInfos(m_itemEntryInter->windowInfos());
updateWindowInfos(m_itemEntry->getExportWindowInfos());
if (m_appSettings)
connect(m_appSettings, &QGSettings::changed, this, &AppItem::onGSettingsChanged);
@ -96,6 +124,8 @@ AppItem::AppItem(DockInter *dockInter, const QGSettings *appSettings, const QGSe
connect(m_activeAppSettings, &QGSettings::changed, this, &AppItem::onGSettingsChanged);
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &AppItem::onThemeTypeChanged);
connect(DGuiApplicationHelper::instance()->systemTheme(), &DPlatformTheme::activeColorChanged, this,
[this](const auto &color) { m_activeColor = color; });
/** 日历 1S定时判断是否刷新icon的处理 */
connect(m_refershIconTimer, &QTimer::timeout, this, &AppItem::onRefreshIcon);
@ -106,7 +136,7 @@ AppItem::AppItem(DockInter *dockInter, const QGSettings *appSettings, const QGSe
*/
void AppItem::checkEntry()
{
m_itemEntryInter->Check();
m_itemEntry->check();
}
const QString AppItem::appId() const
@ -116,12 +146,12 @@ const QString AppItem::appId() const
QString AppItem::name() const
{
return m_itemEntryInter->name();
return m_name;
}
bool AppItem::isValid() const
{
return m_itemEntryInter->isValid() && !m_itemEntryInter->id().isEmpty();
return m_itemEntry->isValid() && !m_id.isEmpty();
}
// Update _NET_WM_ICON_GEOMETRY property for windows that every item
@ -151,7 +181,7 @@ void AppItem::updateWindowIconGeometries()
*/
void AppItem::undock()
{
m_itemEntryInter->RequestUndock();
m_itemEntry->requestUndock();
}
QWidget *AppItem::appDragWidget()
@ -197,28 +227,28 @@ bool AppItem::splitWindowOnScreen(ScreenSpliter::SplitDirection direction)
int AppItem::mode() const
{
return m_itemEntryInter->mode();
return m_mode;
}
DockEntryInter *AppItem::itemEntryInter() const
Entry *AppItem::itemEntry() const
{
return m_itemEntryInter;
return m_itemEntry;
}
QString AppItem::accessibleName()
{
return m_itemEntryInter->name();
return m_name;
}
void AppItem::requestDock()
{
m_itemEntryInter->RequestDock();
m_itemEntry->requestDock();
}
bool AppItem::isDocked() const
{
return m_itemEntryInter->isDocked();
return m_isDocked;
}
qint64 AppItem::appOpenMSecs() const
@ -231,7 +261,7 @@ void AppItem::updateMSecs()
m_createMSecs = QDateTime::currentMSecsSinceEpoch();
}
const WindowInfoMap &AppItem::windowsMap() const
const WindowInfoMap &AppItem::windowsInfos() const
{
return m_windowInfos;
}
@ -273,7 +303,7 @@ void AppItem::paintEvent(QPaintEvent *e)
path.addRoundedRect(backgroundRect, 8, 8);
// 在没有开启窗口多开的情况下,显示背景色
if (!m_dockInter->showMultiWindow()) {
if (!m_showMultiWindow) {
if (m_active) {
QColor color = Qt::black;
color.setAlpha(255 * 0.8);
@ -301,7 +331,9 @@ void AppItem::paintEvent(QPaintEvent *e)
m_verticalIndicator = QPixmap(":/indicator/resources/indicator_ver.svg");
}
m_activeHorizontalIndicator = QPixmap(":/indicator/resources/indicator_active.svg");
m_activeHorizontalIndicator.fill(m_activeColor);
m_activeVerticalIndicator = QPixmap(":/indicator/resources/indicator_active_ver.svg");
m_activeVerticalIndicator.fill(m_activeColor);
switch (DockPosition) {
case Top:
pixmap = m_horizontalIndicator;
@ -365,7 +397,7 @@ void AppItem::mouseReleaseEvent(QMouseEvent *e)
return;
if (e->button() == Qt::MiddleButton) {
m_itemEntryInter->NewInstance(QX11Info::getTimestamp());
m_itemEntry->newInstance(QX11Info::getTimestamp());
// play launch effect
if (m_windowInfos.isEmpty())
@ -377,15 +409,12 @@ void AppItem::mouseReleaseEvent(QMouseEvent *e)
return;
}
qDebug() << "app item clicked, name:" << m_itemEntryInter->name()
<< "id:" << m_itemEntryInter->id() << "my-id:" << m_id << "icon:" << m_itemEntryInter->icon();
if (m_dockInter->showMultiWindow()) {
if (m_showMultiWindow) {
// 如果开启了多窗口显示,则直接新建一个窗口
m_itemEntryInter->NewInstance(QX11Info::getTimestamp());
m_itemEntry->newInstance(QX11Info::getTimestamp());
} else {
// 如果没有开启新窗口显示,则
m_itemEntryInter->Activate(QX11Info::getTimestamp());
m_itemEntry->active(QX11Info::getTimestamp());
// play launch effect
if (m_windowInfos.isEmpty() && DGuiApplicationHelper::isSpecialEffectsEnvironment())
playSwingEffect();
@ -438,7 +467,7 @@ void AppItem::wheelEvent(QWheelEvent *e)
QWidget::wheelEvent(e);
if (qAbs(e->angleDelta().y()) > 20) {
m_itemEntryInter->PresentWindows();
m_itemEntry->presentWindows();
}
}
@ -492,7 +521,7 @@ void AppItem::dropEvent(QDropEvent *e)
}
qDebug() << "accept drop event with URIs: " << uriList;
m_itemEntryInter->HandleDragDrop(QX11Info::getTimestamp(), uriList);
m_itemEntry->handleDragDrop(QX11Info::getTimestamp(), uriList);
}
void AppItem::leaveEvent(QEvent *e)
@ -522,12 +551,12 @@ void AppItem::invokedMenuItem(const QString &itemId, const bool checked)
{
Q_UNUSED(checked);
m_itemEntryInter->HandleMenuItem(QX11Info::getTimestamp(), itemId);
m_itemEntry->handleMenuItem(QX11Info::getTimestamp(), itemId);
}
const QString AppItem::contextMenu() const
{
return m_itemEntryInter->menu();
return m_menu;
}
QWidget *AppItem::popupTips()
@ -540,14 +569,14 @@ QWidget *AppItem::popupTips()
static TipsWidget appNameTips(topLevelWidget());
appNameTips.setAccessibleName("tip");
appNameTips.setObjectName(m_itemEntryInter->name());
appNameTips.setObjectName(m_name);
if (!m_windowInfos.isEmpty()) {
const quint32 currentWindow = m_itemEntryInter->currentWindow();
const quint32 currentWindow = m_currentWindow;
Q_ASSERT(m_windowInfos.contains(currentWindow));
appNameTips.setText(m_windowInfos[currentWindow].title.simplified());
} else {
appNameTips.setText(m_itemEntryInter->name().simplified());
appNameTips.setText(m_name.simplified());
}
return &appNameTips;
@ -632,7 +661,7 @@ void AppItem::updateWindowInfos(const WindowInfoMap &info)
m_windowInfos = info;
if (m_appPreviewTips)
m_appPreviewTips->setWindowInfos(m_windowInfos, m_itemEntryInter->GetAllowedCloseWindows().value());
m_appPreviewTips->setWindowInfos(m_windowInfos, m_itemEntry->getAllowedClosedWindowIds().toList());
m_updateIconGeometryTimer->start();
// process attention effect
@ -654,22 +683,21 @@ void AppItem::refreshIcon()
if (!isVisible())
return;
const QString icon = m_itemEntryInter->icon();
const int iconSize = qMin(width(), height());
if (DockDisplayMode == Efficient)
m_iconValid = ThemeAppIcon::getIcon(m_appIcon, icon, iconSize * 0.7, !m_iconValid);
m_iconValid = ThemeAppIcon::getIcon(m_appIcon, m_icon, iconSize * 0.7, !m_iconValid);
else
m_iconValid = ThemeAppIcon::getIcon(m_appIcon, icon, iconSize * 0.8, !m_iconValid);
m_iconValid = ThemeAppIcon::getIcon(m_appIcon, m_icon, iconSize * 0.8, !m_iconValid);
if (!m_refershIconTimer->isActive() && m_itemEntryInter->icon() == "dde-calendar") {
if (!m_refershIconTimer->isActive() && m_icon == "dde-calendar") {
m_refershIconTimer->start();
}
if (!m_iconValid) {
if (m_retryTimes < 10) {
m_retryTimes++;
qDebug() << m_itemEntryInter->name() << "obtain app icon(" << icon << ")failed, retry times:" << m_retryTimes;
qDebug() << m_name << "obtain app icon(" << m_icon << ")failed, retry times:" << m_retryTimes;
// Maybe the icon was installed after we loaded the caches.
// QIcon::setThemeSearchPaths will force Qt to re-check the gtk cache validity.
QIcon::setThemeSearchPaths(QIcon::themeSearchPaths());
@ -724,14 +752,14 @@ void AppItem::showPreview()
return;
m_appPreviewTips = new PreviewContainer;
m_appPreviewTips->setWindowInfos(m_windowInfos, m_itemEntryInter->GetAllowedCloseWindows().value());
m_appPreviewTips->setWindowInfos(m_windowInfos, m_itemEntry->getAllowedClosedWindowIds().toList());
m_appPreviewTips->updateLayoutDirection(DockPosition);
connect(m_appPreviewTips, &PreviewContainer::requestActivateWindow, this, &AppItem::requestActivateWindow, Qt::QueuedConnection);
connect(m_appPreviewTips, &PreviewContainer::requestActivateWindow, this, &AppItem::activeWindow, Qt::QueuedConnection);
connect(m_appPreviewTips, &PreviewContainer::requestPreviewWindow, this, &AppItem::requestPreviewWindow, Qt::QueuedConnection);
connect(m_appPreviewTips, &PreviewContainer::requestCancelPreviewWindow, this, &AppItem::requestCancelPreview);
connect(m_appPreviewTips, &PreviewContainer::requestHidePopup, this, &AppItem::hidePopup);
connect(m_appPreviewTips, &PreviewContainer::requestCheckWindows, m_itemEntryInter, &DockEntryInter::Check);
connect(m_appPreviewTips, &PreviewContainer::requestCheckWindows, m_itemEntry, &Entry::check);
connect(m_appPreviewTips, &PreviewContainer::requestActivateWindow, this, &AppItem::onResetPreview);
connect(m_appPreviewTips, &PreviewContainer::requestCancelPreviewWindow, this, &AppItem::onResetPreview);
@ -803,7 +831,7 @@ void AppItem::onGSettingsChanged(const QString &key)
return;
}
const QGSettings *setting = m_itemEntryInter->isDocked()
const QGSettings *setting = m_isDocked
? m_dockedAppSettings
: m_activeAppSettings;
@ -815,7 +843,7 @@ void AppItem::onGSettingsChanged(const QString &key)
bool AppItem::checkGSettingsControl() const
{
const QGSettings *setting = m_itemEntryInter->isDocked()
const QGSettings *setting = m_isDocked
? m_dockedAppSettings
: m_activeAppSettings;
@ -845,3 +873,8 @@ void AppItem::showEvent(QShowEvent *e)
refreshIcon();
}
void AppItem::activeWindow(WId wid)
{
m_itemEntry->activeWindow(wid);
}

View File

@ -11,12 +11,15 @@
#include "appdrag.h"
#include "../widgets/tipswidget.h"
#include "dbusutil.h"
#include "taskmanager/entry.h"
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QGraphicsItemAnimation>
#include <DGuiApplicationHelper>
#include <cstdint>
class QGSettings;
class ScreenSpliter;
@ -25,7 +28,7 @@ class AppItem : public DockItem
Q_OBJECT
public:
explicit AppItem(DockInter *dockInter, const QGSettings *appSettings, const QGSettings *activeAppSettings, const QGSettings *dockedAppSettings, const QDBusObjectPath &entry, QWidget *parent = nullptr);
explicit AppItem(const QGSettings *appSettings, const QGSettings *activeAppSettings, const QGSettings *dockedAppSettings, const Entry *entry, QWidget *parent = nullptr);
~AppItem() override;
void checkEntry() override;
@ -42,15 +45,17 @@ public:
bool supportSplitWindow();
bool splitWindowOnScreen(ScreenSpliter::SplitDirection direction);
int mode() const;
DockEntryInter *itemEntryInter() const;
Entry *itemEntry() const;
inline ItemType itemType() const override { return App; }
QPixmap appIcon(){ return m_appIcon; }
uint32_t currentWindow(){ return m_currentWindow; }
virtual QString accessibleName() override;
void requestDock();
bool isDocked() const;
qint64 appOpenMSecs() const;
void updateMSecs();
const WindowInfoMap &windowsMap() const;
const WindowInfoMap &windowsInfos() const;
void activeWindow(WId wid);
signals:
void requestActivateWindow(const WId wid) const;
@ -61,6 +66,7 @@ signals:
void requestUpdateEntryGeometries() const;
void windowCountChanged() const;
void modeChanged(int) const;
void onCurrentWindowChanged(uint32_t currentWindow);
private:
void moveEvent(QMoveEvent *e) override;
@ -104,9 +110,9 @@ private:
const QGSettings *m_appSettings;
const QGSettings *m_activeAppSettings;
const QGSettings *m_dockedAppSettings;
Entry *m_itemEntry;
PreviewContainer *m_appPreviewTips;
DockEntryInter *m_itemEntryInter;
QGraphicsView *m_swingEffectView;
QGraphicsItemAnimation *m_itemAnimation;
@ -116,17 +122,29 @@ private:
QPointer<AppDrag> m_drag;
bool m_active;
bool m_isDocked;
WindowInfoMap m_windowInfos;
int32_t m_mode;
QString m_desktopfile;
QString m_icon;
QString m_id;
QString m_menu;
QString m_name;
uint32_t m_currentWindow;
int m_retryTimes;
bool m_iconValid;
quint64 m_lastclickTimes;
bool m_showMultiWindow;
WindowInfoMap m_windowInfos;
QString m_id;
QPixmap m_appIcon;
// 统一样式?
QPixmap m_horizontalIndicator;
QPixmap m_verticalIndicator;
QPixmap m_activeHorizontalIndicator;
QPixmap m_activeVerticalIndicator;
QColor m_activeColor;
QTimer *m_updateIconGeometryTimer;
QTimer *m_retryObtainIconTimer;
@ -140,7 +158,6 @@ private:
static QPoint MousePressPos;
ScreenSpliter *m_screenSpliter;
DockInter *m_dockInter;
};
#endif // APPITEM_H

View File

@ -6,6 +6,7 @@
#include "appitem.h"
#include "appmultiitem.h"
#include "imageutil.h"
#include "screenspliter.h"
#include "themeappicon.h"
#include <QBitmap>
@ -23,7 +24,6 @@ AppMultiItem::AppMultiItem(AppItem *appItem, WId winId, const WindowInfo &window
: DockItem(parent)
, m_appItem(appItem)
, m_windowInfo(windowInfo)
, m_entryInter(appItem->itemEntryInter())
, m_winId(winId)
, m_menu(new QMenu(this))
{
@ -70,12 +70,12 @@ void AppMultiItem::initMenu()
void AppMultiItem::initConnection()
{
connect(m_entryInter, &DockEntryInter::CurrentWindowChanged, this, &AppMultiItem::onCurrentWindowChanged);
connect(m_appItem, &AppItem::onCurrentWindowChanged, this, &AppMultiItem::onCurrentWindowChanged);
}
void AppMultiItem::onOpen()
{
m_entryInter->ActiveWindow(m_winId);
m_appItem->activeWindow(m_winId);
}
void AppMultiItem::onCurrentWindowChanged(uint32_t value)
@ -103,7 +103,7 @@ void AppMultiItem::paintEvent(QPaintEvent *)
path.addRoundedRect(rect(), radius, radius);
painter.fillPath(path, Qt::transparent);
if (m_entryInter->currentWindow() == m_winId) {
if (m_appItem->currentWindow() == m_winId) {
QColor backColor = Qt::black;
backColor.setAlpha(255 * 0.8);
painter.fillPath(path, backColor);
@ -117,7 +117,7 @@ void AppMultiItem::paintEvent(QPaintEvent *)
painter.drawPixmap(QRect(x, y, itemWidth, itemHeight), m_pixmap);
QPixmap pixmapAppIcon;
ThemeAppIcon::getIcon(pixmapAppIcon, m_entryInter->icon(), qMin(width(), height()) * 0.8);
ThemeAppIcon::getIcon(pixmapAppIcon, m_appItem->appId(), qMin(width(), height()) * 0.8);
if (!pixmapAppIcon.isNull()) {
// 绘制下方的图标,下方的小图标大约为应用图标的三分之一的大小
//pixmap = pixmap.scaled(pixmap.width() * 0.3, pixmap.height() * 0.3);
@ -135,7 +135,7 @@ void AppMultiItem::paintEvent(QPaintEvent *)
void AppMultiItem::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
m_entryInter->ActiveWindow(m_winId);
m_appItem->activeWindow(m_winId);
} else {
QPoint currentPoint = QCursor::pos();
m_menu->exec(currentPoint);

View File

@ -8,6 +8,7 @@
#include "dockitem.h"
#include "dbusutil.h"
#include "taskmanager/windowinfomap.h"
class AppItem;
@ -43,7 +44,6 @@ private Q_SLOTS:
private:
AppItem *m_appItem;
WindowInfo m_windowInfo;
DockEntryInter *m_entryInter;
QPixmap m_pixmap;
WId m_winId;
QMenu *m_menu;

View File

@ -46,7 +46,7 @@ QPixmap AppDrag::pixmap() const
Qt::DropAction AppDrag::start(Qt::DropActions supportedActions)
{
m_appDragWidget->show();
return QDrag::start(supportedActions);
return QDrag::exec(supportedActions);
}
Qt::DropAction AppDrag::exec(Qt::DropActions supportedActions)

View File

@ -32,12 +32,6 @@ AppDragWidget::AppDragWidget(QWidget *parent)
, m_item(nullptr)
, m_dockScreen(nullptr)
{
m_popupWindow->setShadowBlurRadius(20);
m_popupWindow->setRadius(18);
m_popupWindow->setShadowYOffset(2);
m_popupWindow->setShadowXOffset(0);
m_popupWindow->setArrowWidth(18);
m_popupWindow->setArrowHeight(10);
m_popupWindow->setRadius(18);
m_scene->addItem(m_object.get());

View File

@ -6,6 +6,8 @@
#include "appsnapshot.h"
#include "previewcontainer.h"
#include "../widgets/tipswidget.h"
#include "taskmanager/taskmanager.h"
#include "taskmanager/xcbutils.h"
#include "utils.h"
#include "imageutil.h"
@ -23,6 +25,9 @@
#include <QSizeF>
#include <QTimer>
#include <QPainterPath>
#include <QDBusConnectionInterface>
#include <QDBusInterface>
#include <QDBusReply>
struct SHMInfo {
long shmid;
@ -44,14 +49,13 @@ using namespace Dock;
AppSnapshot::AppSnapshot(const WId wid, QWidget *parent)
: QWidget(parent)
, m_wid(wid)
, m_closeAble(false)
, m_closeAble(true)
, m_isWidowHidden(false)
, m_title(new TipsWidget(this))
, m_3DtitleBtn(nullptr)
, m_waitLeaveTimer(new QTimer(this))
, m_closeBtn2D(new DIconButton(this))
, m_wmHelper(DWindowManagerHelper::instance())
, m_dockDaemonInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this))
{
m_closeBtn2D->setFixedSize(SNAP_CLOSE_BTN_WIDTH, SNAP_CLOSE_BTN_WIDTH);
m_closeBtn2D->setIconSize(QSize(SNAP_CLOSE_BTN_WIDTH, SNAP_CLOSE_BTN_WIDTH));
@ -79,7 +83,7 @@ AppSnapshot::AppSnapshot(const WId wid, QWidget *parent)
void AppSnapshot::setWindowState()
{
if (m_isWidowHidden) {
m_dockDaemonInter->MinimizeWindow(m_wid);
TaskManager::instance()->MinimizeWindow(m_wid);
}
}
@ -130,7 +134,7 @@ void AppSnapshot::setTitleVisible(bool bVisible)
void AppSnapshot::closeWindow() const
{
if (Utils::IS_WAYLAND_DISPLAY) {
m_dockDaemonInter->CloseWindow(static_cast<uint>(m_wid));
TaskManager::instance()->closeWindow(static_cast<uint>(m_wid));
} else {
const auto display = QX11Info::display();
if (!display) {
@ -226,7 +230,7 @@ void AppSnapshot::fetchSnapshot()
emit requestCheckWindow();
return;
}
qimage = QImage((const uchar *)(ximage->data), ximage->width, ximage->height, ximage->bytes_per_line, QImage::Format_RGB32);
qimage = QImage(reinterpret_cast<uchar*>(ximage->data), ximage->width, ximage->height, ximage->bytes_per_line, QImage::Format_RGB32).copy();
}
Q_ASSERT(!qimage.isNull());
@ -293,7 +297,9 @@ void AppSnapshot::paintEvent(QPaintEvent *e)
const int radius = dstyle.pixelMetric(DStyle::PM_FrameRadius);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
QRect imageRect(8, 8, width() - 16, height() - 16);
QSize size = m_pixmap.size().scaled(width() - 16, height() - 16, Qt::KeepAspectRatio);
QRect imageRect((width() - size.width()) / 2, (height() - size.height()) / 2, size.width(), size.height());
painter.setPen(Qt::NoPen);
QPainterPath path;
path.addRoundedRect(imageRect, radius * ratio, radius * ratio);
@ -311,17 +317,16 @@ void AppSnapshot::mousePressEvent(QMouseEvent *e)
bool AppSnapshot::eventFilter(QObject *watched, QEvent *e)
{
if (watched == m_closeBtn2D) {
// TODO 判断条件重复
if (watched == m_closeBtn2D && (e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverMove)) {
if (e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverMove) {
m_closeBtn2D->setIcon(QIcon(":/icons/resources/close_round_hover.svg"));
} else if (watched == m_closeBtn2D && e->type() == QEvent::HoverLeave) {
} else if (e->type() == QEvent::HoverLeave) {
m_closeBtn2D->setIcon(QIcon(":/icons/resources/close_round_normal.svg"));
} else if (watched == m_closeBtn2D && e->type() == QEvent::MouseButtonPress) {
} else if (e->type() == QEvent::MouseButtonPress) {
m_closeBtn2D->setIcon(QIcon(":/icons/resources/close_round_press.svg"));
}
}
return false;
return QWidget::eventFilter(watched, e);
}
void AppSnapshot::resizeEvent(QResizeEvent *event)

View File

@ -7,6 +7,7 @@
#define APPSNAPSHOT_H
#include "dbusutil.h"
#include "taskmanager/windowinfomap.h"
#include <DIconButton>
#include <DWindowManagerHelper>
@ -99,7 +100,6 @@ private:
QTimer *m_waitLeaveTimer;
DIconButton *m_closeBtn2D;
DWindowManagerHelper *m_wmHelper;
DockInter *m_dockDaemonInter;
};
#endif // APPSNAPSHOT_H

View File

@ -126,14 +126,14 @@ void FloatingPreview::mouseReleaseEvent(QMouseEvent *e)
bool FloatingPreview::eventFilter(QObject *watched, QEvent *event)
{
if(watched == m_closeBtn3D) {
if(watched == m_closeBtn3D && (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverMove)) {
if (watched == m_closeBtn3D) {
if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverMove) {
m_closeBtn3D->setIcon(QIcon(":/icons/resources/close_round_hover.svg"));
}
else if (watched == m_closeBtn3D && event->type() == QEvent::HoverLeave) {
else if (event->type() == QEvent::HoverLeave) {
m_closeBtn3D->setIcon(QIcon(":/icons/resources/close_round_normal.svg"));
}
else if (watched == m_closeBtn3D && event->type() == QEvent::MouseButtonPress) {
else if (event->type() == QEvent::MouseButtonPress) {
m_closeBtn3D->setIcon(QIcon(":/icons/resources/close_round_press.svg"));
}
}

View File

@ -255,7 +255,7 @@ void PreviewContainer::onSnapshotClicked(const WId wid)
Q_EMIT requestActivateWindow(wid);
m_needActivate = true;
m_waitForShowPreviewTimer->stop();
requestHidePopup();
Q_EMIT requestHidePopup();
}
void PreviewContainer::previewEntered(const WId wid)

View File

@ -17,7 +17,7 @@
#include <DWindowManagerHelper>
DWIDGET_USE_NAMESPACE
typedef QList<quint32> WindowList;
class PreviewContainer : public QWidget
{
Q_OBJECT

View File

@ -31,19 +31,14 @@ DockItem::DockItem(QWidget *parent)
, m_popupAdjustDelayTimer(new QTimer(this))
{
if (PopupWindow.isNull()) {
DockPopupWindow *arrowRectangle = new DockPopupWindow(nullptr);
arrowRectangle->setShadowBlurRadius(20);
arrowRectangle->setRadius(18);
arrowRectangle->setShadowYOffset(2);
arrowRectangle->setShadowXOffset(0);
arrowRectangle->setArrowWidth(18);
arrowRectangle->setArrowHeight(10);
arrowRectangle->setObjectName("apppopup");
DockPopupWindow *blurRectangle = new DockPopupWindow(nullptr);
blurRectangle->setRadius(18);
blurRectangle->setObjectName("apppopup");
if (Utils::IS_WAYLAND_DISPLAY) {
Qt::WindowFlags flags = arrowRectangle->windowFlags() | Qt::FramelessWindowHint;
arrowRectangle->setWindowFlags(flags);
Qt::WindowFlags flags = blurRectangle->windowFlags() | Qt::FramelessWindowHint;
blurRectangle->setWindowFlags(flags);
}
PopupWindow = arrowRectangle;
PopupWindow = blurRectangle;
connect(qApp, &QApplication::aboutToQuit, PopupWindow, &DockPopupWindow::deleteLater);
}
@ -271,9 +266,9 @@ void DockItem::showHoverTips()
void DockItem::showPopupWindow(QWidget *const content, const bool model)
{
if(itemType() == App){
if (itemType() == App) {
PopupWindow->setRadius(18);
}else {
} else {
PopupWindow->setRadius(6);
}
@ -288,13 +283,8 @@ void DockItem::showPopupWindow(QWidget *const content, const bool model)
if (lastContent)
lastContent->setVisible(false);
switch (DockPosition) {
case Top: popup->setArrowDirection(DockPopupWindow::ArrowTop); break;
case Bottom: popup->setArrowDirection(DockPopupWindow::ArrowBottom); break;
case Left: popup->setArrowDirection(DockPopupWindow::ArrowLeft); break;
case Right: popup->setArrowDirection(DockPopupWindow::ArrowRight); break;
}
popup->resize(content->sizeHint());
popup->setPosition(DockPosition);
popup->setContent(content);
const QPoint p = popupMarkPoint();
@ -359,16 +349,16 @@ const QPoint DockItem::popupMarkPoint()
const QRect r = rect();
switch (DockPosition) {
case Top:
p += QPoint(r.width() / 2, r.height());
p += QPoint(r.width() / 2, r.height() + POPUP_PADDING);
break;
case Bottom:
p += QPoint(r.width() / 2, 0);
p += QPoint(r.width() / 2, -POPUP_PADDING);
break;
case Left:
p += QPoint(r.width(), r.height() / 2);
p += QPoint(r.width() + POPUP_PADDING, r.height() / 2);
break;
case Right:
p += QPoint(0, r.height() / 2);
p += QPoint(-POPUP_PADDING, r.height() / 2);
break;
}
return p;

View File

@ -14,6 +14,7 @@
#include <QMouseEvent>
#include <QApplication>
#include <QGSettings>
#include <QtConcurrent>
#include <QDBusInterface>
#include <QDBusPendingCall>
#include <DDBusSender>
@ -84,15 +85,17 @@ void LauncherItem::mouseReleaseEvent(QMouseEvent *e)
if (e->button() != Qt::LeftButton)
return;
DDBusSender dbusSender = DDBusSender()
QtConcurrent::run([=] {
DDBusSender dbusSender = DDBusSender()
.service(launcherService)
.path(launcherPath)
.interface(launcherInterface);
QDBusPendingReply<bool> visibleReply = dbusSender.property("Visible").get();
if (!visibleReply.value())
dbusSender.method("Toggle").call();
QDBusPendingReply<bool> visibleReply = dbusSender.property("Visible").get();
if (!visibleReply.value())
dbusSender.method("Toggle").call();
});
}
QWidget *LauncherItem::popupTips()

View File

@ -278,9 +278,9 @@ void PluginsItem::mouseClicked()
if (!command.isEmpty()) {
QProcess *proc = new QProcess(this);
connect(proc, static_cast<void (QProcess::*)(int)>(&QProcess::finished), proc, &QProcess::deleteLater);
connect(proc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), proc, &QProcess::deleteLater);
proc->startDetached(command);
proc->startDetached(command, {});
return;
}

View File

@ -4,16 +4,14 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "mainwindow.h"
#include "accessible.h"
#include "dbusdockadaptors.h"
#include "dockdaemonadaptors.h"
#include "utils.h"
#include "themeappicon.h"
#include "dockitemmanager.h"
#include "dockapplication.h"
#include "traymainwindow.h"
#include "windowmanager.h"
#include <QAccessible>
#include <QDir>
#include <QStandardPaths>
#include <QDateTime>
@ -41,8 +39,6 @@ DUTIL_USE_NAMESPACE
const QString g_cfgPath = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation)[0] + "/dde-cfg.ini";
using namespace std;
/**
* @brief IsSaveMode
* @return
@ -152,14 +148,21 @@ bool IsSaveMode()
int main(int argc, char *argv[])
{
if (QString(getenv("XDG_CURRENT_DESKTOP")).compare("deepin", Qt::CaseInsensitive) == 0) {
QString currentDesktop = QString(getenv("XDG_CURRENT_DESKTOP"));
if (currentDesktop.compare("DDE", Qt::CaseInsensitive) == 0 ||
currentDesktop.compare("deepin", Qt::CaseInsensitive) == 0) {
qDebug() << "Warning: force enable D_DXCB_FORCE_NO_TITLEBAR now!";
setenv("D_DXCB_FORCE_NO_TITLEBAR", "1", 1);
}
DGuiApplicationHelper::setAttribute(DGuiApplicationHelper::UseInactiveColorGroup, false);
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);
@ -170,16 +173,12 @@ int main(int argc, char *argv[])
app.setOrganizationName("deepin");
app.setApplicationName("dde-dock");
app.setApplicationDisplayName("DDE Dock");
app.setApplicationVersion("2.0");
app.setApplicationVersion(CVERSION);
app.loadTranslator();
app.setAttribute(Qt::AA_EnableHighDpiScaling, true);
app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
// 自动化标记由此开始
QAccessible::installFactory(accessibleFactory);
// 设置日志输出到控制台以及文件
DLogManager::setLogFormat("%{time}{yyyyMMdd.HH:mm:ss.zzz}[%{type:1}][%{function:-35} %{line:-4}] %{message}\n");
DLogManager::setLogFormat("%{time}{yyMMdd.HH:mm:ss.zzz}[%{type:1}] [%{category}] [%{function:-25} %{line:-4}] %{message}");
DLogManager::registerConsoleAppender();
DLogManager::registerFileAppender();
@ -224,10 +223,15 @@ int main(int argc, char *argv[])
// 注册任务栏的DBus服务
DBusDockAdaptors adaptor(&windowManager);
DockDaemonDBusAdaptor daemonAdaptor(&windowManager);
QDBusConnection::sessionBus().registerService("org.deepin.dde.Dock1");
QDBusConnection::sessionBus().registerObject("/org/deepin/dde/Dock1", "org.deepin.dde.Dock1", &windowManager);
//保证dock daemon接口兼容性,dde-desktop,dde-clipboard,deepin-system-monitor,dde-osd等在调用。
QDBusConnection::sessionBus().registerService("org.deepin.dde.daemon.Dock1");
QDBusConnection::sessionBus().registerObject("/org/deepin/dde/daemon/Dock1", "org.deepin.dde.daemon.Dock1", &windowManager);
// 当任务栏以-r参数启动时设置CANSHOW未false之后调用launch不显示任务栏
qApp->setProperty("CANSHOW", !parser.isSet(runOption));

View File

@ -14,10 +14,9 @@ bool ScreenSpliter::releaseSplit()
return true;
}
ScreenSpliter::ScreenSpliter(AppItem *appItem, DockEntryInter *entryInter, QObject *parent)
ScreenSpliter::ScreenSpliter(AppItem *appItem, QObject *parent)
: QObject(parent)
, m_appItem(appItem)
, m_entryInter(entryInter)
{
}
@ -31,15 +30,10 @@ AppItem *ScreenSpliter::appItem() const
return m_appItem;
}
DockEntryInter *ScreenSpliter::entryInter() const
{
return m_entryInter;
}
ScreenSpliter *ScreenSpliterFactory::createScreenSpliter(AppItem *appItem, DockEntryInter *entryInter)
ScreenSpliter *ScreenSpliterFactory::createScreenSpliter(AppItem *appItem)
{
if (Utils::IS_WAYLAND_DISPLAY)
return new ScreenSpliter_Wayland(appItem, entryInter, appItem);
return new ScreenSpliter_Wayland(appItem, appItem);
return new ScreenSpliter_Xcb(appItem, entryInter, appItem);
return new ScreenSpliter_Xcb(appItem, appItem);
}

View File

@ -37,20 +37,18 @@ public:
virtual bool releaseSplit(); // 释放分屏
protected:
explicit ScreenSpliter(AppItem *appItem, DockEntryInter *entryInter, QObject *parent = nullptr);
explicit ScreenSpliter(AppItem *appItem, QObject *parent = nullptr);
virtual ~ScreenSpliter();
AppItem *appItem() const;
DockEntryInter *entryInter() const;
private:
AppItem *m_appItem;
DockEntryInter *m_entryInter;
};
class ScreenSpliterFactory
{
public:
static ScreenSpliter *createScreenSpliter(AppItem *appItem, DockEntryInter *entryInter);
static ScreenSpliter *createScreenSpliter(AppItem *appItem);
};
#endif // SCREENSPLITER_H

View File

@ -10,20 +10,14 @@
#include <QApplication>
#include <QX11Info>
#include <QtWaylandClient>
#define private public
#include <private/qwaylandintegration_p.h>
#include <private/qwaylandshellsurface_p.h>
#include <private/qwaylandwindow_p.h>
#include <private/qwaylandcursor_p.h>
#undef private
#include <registry.h>
#include <ddeshell.h>
#include <event_queue.h>
#include <plasmashell.h>
#include <compositor.h>
#include <clientmanagement.h>
#include <connection_thread.h>
#include <DWayland/Client/registry.h>
#include <DWayland/Client/ddeshell.h>
#include <DWayland/Client/event_queue.h>
#include <DWayland/Client/plasmashell.h>
#include <DWayland/Client/compositor.h>
#include <DWayland/Client/clientmanagement.h>
#include <DWayland/Client/connection_thread.h>
SplitWindowManager *ScreenSpliter_Wayland::m_splitManager = nullptr;
@ -31,8 +25,8 @@ SplitWindowManager *ScreenSpliter_Wayland::m_splitManager = nullptr;
* @brief ScreenSpliter_Wayland::ScreenSpliter_Wayland
* @param parent
*/
ScreenSpliter_Wayland::ScreenSpliter_Wayland(AppItem *appItem, DockEntryInter *entryInter, QObject *parent)
: ScreenSpliter(appItem, entryInter, parent)
ScreenSpliter_Wayland::ScreenSpliter_Wayland(AppItem *appItem, QObject *parent)
: ScreenSpliter(appItem, parent)
{
if (!m_splitManager)
m_splitManager = new SplitWindowManager;
@ -58,7 +52,7 @@ void ScreenSpliter_Wayland::setMaskVisible(const QRect &rect, bool visible)
DPalette palette = DGuiApplicationHelper::instance()->applicationPalette();
QColor backColor = palette.color(QPalette::Highlight);
backColor.setAlpha(255 * 0.3);
palette.setBrush(QPalette::ColorRole::Background, backColor);
palette.setBrush(QPalette::ColorRole::Window, backColor);
desktopWidget->setPalette(palette);
desktopWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
}
@ -74,7 +68,7 @@ bool ScreenSpliter_Wayland::split(SplitDirection direction)
if (!suportSplitScreen())
return false;
WindowInfoMap windowInfos = entryInter()->windowInfos();
WindowInfoMap windowInfos = appItem()->windowsInfos();
m_splitManager->requestSplitWindow(windowInfos.first().uuid.toStdString().c_str(), direction);
return true;
@ -88,7 +82,7 @@ bool ScreenSpliter_Wayland::windowSupportSplit(const QString &uuid) const
bool ScreenSpliter_Wayland::suportSplitScreen()
{
// 判断所有打开的窗口列表,只要有一个窗口支持分屏,就认为它支持分屏
const WindowInfoMap &windowsInfo = entryInter()->windowInfos();
const WindowInfoMap &windowsInfo = appItem()->windowsInfos();
for (const WindowInfo &windowInfo : windowsInfo) {
if (windowSupportSplit(windowInfo.uuid))
return true;

View File

@ -9,6 +9,7 @@
#include "screenspliter.h"
#include <QWidget>
#include <QMap>
namespace KWayland {
namespace Client {
@ -38,7 +39,7 @@ class ScreenSpliter_Wayland : public ScreenSpliter
Q_OBJECT
public:
explicit ScreenSpliter_Wayland(AppItem *appItem, DockEntryInter *entryInter, QObject *parent);
explicit ScreenSpliter_Wayland(AppItem *appItem, QObject *parent);
~ScreenSpliter_Wayland() override;
void startSplit(const QRect &rect) override;

View File

@ -61,8 +61,8 @@ static QByteArray windowProperty(quint32 WId, xcb_atom_t propAtom, xcb_atom_t ty
return data;
}
ScreenSpliter_Xcb::ScreenSpliter_Xcb(AppItem *appItem, DockEntryInter *entryInter, QObject *parent)
: ScreenSpliter(appItem, entryInter, parent)
ScreenSpliter_Xcb::ScreenSpliter_Xcb(AppItem *appItem, QObject *parent)
: ScreenSpliter(appItem, parent)
{
}
@ -79,7 +79,7 @@ bool ScreenSpliter_Xcb::split(ScreenSpliter::SplitDirection direction)
if (!suportSplitScreen())
return false;
quint32 WId = entryInter()->windowInfos().keys().first();
quint32 WId = appItem()->windowsInfos().keys().first();
xcb_client_message_event_t xev;
xev.response_type = XCB_CLIENT_MESSAGE;
xev.type = internAtom("_DEEPIN_SPLIT_WINDOW", false);
@ -116,7 +116,7 @@ void ScreenSpliter_Xcb::showSplitScreenEffect(const QRect &rect, bool visible)
if (!suportSplitScreen())
return;
quint32 WId = entryInter()->windowInfos().keys().first();
quint32 WId = appItem()->windowsInfos().keys().first();
// 触发分屏的效果
xcb_client_message_event_t xev;
xev.response_type = XCB_CLIENT_MESSAGE;
@ -137,7 +137,7 @@ void ScreenSpliter_Xcb::showSplitScreenEffect(const QRect &rect, bool visible)
bool ScreenSpliter_Xcb::suportSplitScreen()
{
// 判断所有的窗口,只要有一个窗口支持分屏,就认为它支持分屏
QList<quint32> winIds = entryInter()->windowInfos().keys();
QList<quint32> winIds = appItem()->windowsInfos().keys();
for (const quint32 &winId : winIds) {
if (windowSupportSplit(winId))
return true;

View File

@ -16,7 +16,7 @@ typedef QMap<quint32, WindowInfo> WindowInfoMap;
class ScreenSpliter_Xcb : public ScreenSpliter
{
public:
explicit ScreenSpliter_Xcb(AppItem *appItem, DockEntryInter *entryInter, QObject *parent = nullptr);
explicit ScreenSpliter_Xcb(AppItem *appItem, QObject *parent = nullptr);
void startSplit(const QRect &rect) override;
bool split(ScreenSpliter::SplitDirection direction) override;

View File

@ -0,0 +1,60 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "appinfo.h"
#include "common.h"
#include <QDebug>
#include <QString>
#include <QCryptographicHash>
AppInfo::AppInfo(DesktopInfo &info)
: m_installed(false)
, m_isValid(true)
{
init(info);
}
AppInfo::AppInfo(const QString &_fileName)
: m_isValid(true)
{
DesktopInfo info(_fileName);
init(info);
}
void AppInfo::init(DesktopInfo &info)
{
if (!info.isValidDesktop()) {
m_isValid = false;
return;
}
QString xDeepinVendor = info.getDesktopFile()->value(MainSection + "/X-Deepin-Vendor").toString();
if (xDeepinVendor == "deepin") {
m_name = info.getGenericName();
if (m_name.isEmpty()) {
m_name = info.getName();
}
} else {
m_name = info.getName();
}
m_innerId = genInnerIdWithDesktopInfo(info);
m_fileName = info.getDesktopFilePath();
m_id = info.getId();
m_icon = info.getIcon();
m_installed = info.isInstalled();
auto actions = info.getActions();
std::copy(actions.begin(), actions.end(), std::back_inserter(m_actions));
}
QString AppInfo::genInnerIdWithDesktopInfo(DesktopInfo &info)
{
QString cmdline = info.getCommandLine();
QByteArray encryText = QCryptographicHash::hash(QString(cmdline).toLatin1(), QCryptographicHash::Md5);
QString innerId = desktopHashPrefix + encryText.toHex();
qInfo() << "app: " << info.getId() << " generate innerId: " << innerId;
return innerId;
}

View File

@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef APPINFO_H
#define APPINFO_H
#include "desktopinfo.h"
#include <QVector>
// 应用信息类
class AppInfo
{
public:
explicit AppInfo(DesktopInfo &info);
explicit AppInfo(const QString &_fileName);
void init(DesktopInfo &info);
void setIdentifyMethod(QString method) {m_identifyMethod = method;}
bool isValidApp() {return m_isValid;}
bool isInstalled() {return m_installed;}
QString getId() {return m_id;}
QString getIcon() {return m_icon;}
QString getName() {return m_name;}
QString getInnerId() {return m_innerId;}
QString getFileName() {return m_fileName;}
QString getIdentifyMethod() {return m_identifyMethod;}
QVector<DesktopAction> getActions() {return m_actions;}
private:
QString genInnerIdWithDesktopInfo(DesktopInfo &info);
private:
bool m_installed;
bool m_isValid;
QString m_id;
QString m_name;
QString m_icon;
QString m_innerId;
QString m_fileName;
QString m_identifyMethod;
QVector<DesktopAction> m_actions;
};
#endif // APPINFO_H

View File

@ -0,0 +1,80 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "appmenu.h"
#include <QJsonArray>
#include <QJsonDocument>
AppMenu::AppMenu()
: m_itemCount(0)
, m_dirty(false)
, m_checkableMenu(false)
, m_singleCheck(false)
{
}
/**
* @brief AppMenu::appendItem
* @param item
*/
void AppMenu::appendItem(AppMenuItem item)
{
if (!item.text.isEmpty()) {
item.id = allocateId();
m_items.push_back(item);
}
}
/**
* @brief AppMenu::handleAction
* @param timestamp
* @param itemId
*/
void AppMenu::handleAction(uint32_t timestamp, QString itemId)
{
for (auto &item : m_items) {
if (item.id == itemId) {
item.action(timestamp);
break;
}
}
}
void AppMenu::setDirtyStatus(bool isDirty)
{
m_dirty = isDirty;
}
QString AppMenu::getMenuJsonStr()
{
QJsonObject obj;
QJsonArray array;
for (auto item : m_items) {
QJsonObject objItem;
objItem["itemId"] = item.id;
objItem["itemText"] = item.text;
objItem["isActive"] = item.isActive;
objItem["isCheckable"] = item.isCheckable;
objItem["checked"] = item.checked;
objItem["itemIcon"] = item.icon;
objItem["itemIconHover"] = item.iconHover;
objItem["itemIconInactive"] = item.iconInactive;
objItem["showCheckMark"] = item.showCheckMark;
objItem["itemSubMenu"] = item.subMenu ? item.subMenu->getMenuJsonStr() : "";
array.push_back(objItem);
}
obj["items"] = QJsonValue(array);
obj["checkableMenu"] = m_checkableMenu;
obj["singleCheck"] = m_singleCheck;
QString ret = QJsonDocument(obj).toJson();
return ret;
}
QString AppMenu::allocateId()
{
return QString::number(m_itemCount++);
}

View File

@ -0,0 +1,67 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef APPMENU_H
#define APPMENU_H
#include <QString>
#include <QJsonObject>
#include <QVector>
#include <memory>
#include <vector>
#include <functional>
typedef std::function<void(uint32_t)> AppMenuAction;
class AppMenu;
// 应用菜单选项
struct AppMenuItem
{
AppMenuItem()
: isActive(true)
, hint(0)
{
}
QString id;
QString text;
QString isCheckable;
QString checked;
QString icon;
QString iconHover;
QString iconInactive;
QString showCheckMark;
std::shared_ptr<AppMenu> subMenu;
bool isActive;
int hint;
AppMenuAction action;
};
// 应用菜单类
class AppMenu
{
public:
AppMenu();
void appendItem(AppMenuItem item);
void setDirtyStatus(bool isDirty);
void handleAction(uint32_t timestamp, QString itemId);
QString getMenuJsonStr();
private:
QString allocateId();
private:
int m_itemCount;
bool m_dirty;
bool m_checkableMenu; // json:"checkableMenu"
bool m_singleCheck; // json:"singleCheck"
QVector<AppMenuItem> m_items; // json:"items"
};
#endif // APPMENU_H

View File

@ -0,0 +1,89 @@
// SPDX-FileCopyrightText: 2022 ~ 2022 Deepin Technology Co., Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "bamfdesktop.h"
#include <QDir>
#include <qstandardpaths.h>
#define BAMF_INDEX_NAME "bamf-2.index"
BamfDesktop *BamfDesktop::instance()
{
static BamfDesktop instance;
return &instance;
}
QString BamfDesktop::fileName(const QString &instanceName) const
{
for (const BamfData &lineData: m_bamfLineData) {
if (lineData.instanceName.toLower() == instanceName.toLower()) {
QString name = lineData.lineData.split("\t").first();
return QString("%1%2").arg(lineData.directory).arg(name);
}
}
// 如果根据instanceName没有找到则根据空格来进行分隔
for (const BamfData &lineData: m_bamfLineData) {
QStringList lines = lineData.lineData.split("\t");
if (lines.size() < 2)
continue;
QStringList cmds = lines[2].split(" ");
if (cmds.size() > 1 && cmds[1].toLower() == instanceName.toLower())
return QString("%1%2").arg(lineData.directory).arg(lines.first());
}
return instanceName;
}
BamfDesktop::BamfDesktop()
{
loadDesktopFiles();
}
BamfDesktop::~BamfDesktop()
{
}
QStringList BamfDesktop::applicationDirs() const
{
QStringList appDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
QStringList directions;
for (auto appDir : appDirs)
directions << appDir;
return directions;
}
void BamfDesktop::loadDesktopFiles()
{
QStringList directions = applicationDirs();
for (const QString &direction : directions) {
// 读取后缀名为
QDir dir(direction);
dir.setNameFilters(QStringList() << BAMF_INDEX_NAME);
QFileInfoList fileList = dir.entryInfoList();
if (fileList.size() == 0)
continue;
QFileInfo fileInfo = fileList.at(0);
QFile file(fileInfo.absoluteFilePath());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
continue;
QList<QPair<QString, QString>> bamfLine;
while (!file.atEnd()) {
QString line = file.readLine();
QStringList part = line.split("\t");
BamfData bamf;
bamf.directory = direction;
if (part.size() > 2)
bamf.instanceName = part[2].trimmed();
bamf.lineData = line;
m_bamfLineData << bamf;
}
}
}

View File

@ -0,0 +1,37 @@
// SPDX-FileCopyrightText: 2022 ~ 2022 Deepin Technology Co., Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef BAMFDESKTOP_H
#define BAMFDESKTOP_H
#include <QObject>
#include <QMap>
struct BamfData {
QString directory;
QString instanceName;
QString lineData;
};
class BamfDesktop
{
public:
static BamfDesktop *instance();
QString fileName(const QString &instanceName) const;
protected:
BamfDesktop();
~BamfDesktop();
private:
QStringList applicationDirs() const;
void loadDesktopFiles();
private:
QList<BamfData> m_bamfLineData;
};
#endif // BAMFDESKTOP_H

View File

@ -0,0 +1,89 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef COMMON_H
#define COMMON_H
#include <QMap>
#include <QDir>
#include <QString>
#include <QStandardPaths>
const QString configDock = "com.deepin.dde.dock";
const QString configAppearance = "com.deepin.dde.appearance";
const QString keyOpacity = "Opacity";
const QString keyPosition = "Position";
const QString keyIconSize = "Icon_Size";
const QString keyHideMode = "Hide_Mode";
const QString keyRecentApp = "Recent_App";
const QString keyShowRecent = "Show_Recent";
const QString keyDockedApps = "Docked_Apps";
const QString keyDisplayMode = "Display_Mode";
const QString keyShowTimeout = "Show_Timeout";
const QString keyHideTimeout = "Hide_Timeout";
const QString keyForceQuitApp = "Force_Quit_App";
const QString keyPluginSettings = "Plugin_Settings";
const QString keyShowMultiWindow = "Show_MultiWindow";
const QString keyWindowSizeFashion = "Window_Size_Fashion";
const QString keyWindowSizeEfficient = "Window_Size_Efficient";
const QString keyWinIconPreferredApps = "Win_Icon_Preferred_Apps";
constexpr auto DesktopFileActionKey = u8"Desktop Action ";
constexpr auto DDEApplicationManager1ObjectPath = u8"/org/desktopspec/ApplicationManager1";
constexpr auto ApplicationManager1DBusName= u8"org.desktopspec.ApplicationManager1";
static const QString scratchDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation).append("/deepin/dde-dock/scratch/");
const QString desktopHashPrefix = "d:";
const QString windowHashPrefix = "w:";
// 驻留应用desktop file模板
// 由于Icon存储的直接是icon base64压缩后的数据需要“”防止被desktopfile当成stringlist从而导致获取icon失败
const QString dockedItemTemplate = R"([Desktop Entry]
Name=%1
Exec=%2
Icon="%3"
Type=Application
Terminal=false
StartupNotify=false
)";
const QString frontendWindowWmClass = "dde-dock";
const QString ddeLauncherWMClass = "dde-launcher";
const int smartHideTimerDelay = 400;
const int configureNotifyDelay = 100;
const int bestIconSize = 48;
const int menuItemHintShowAllWindows = 1;
const int MotifHintStatus = 8;
const int MotifHintFunctions = 1;
const int MotifHintInputMode = 4;
const int MotifHintDecorations = 2;
const int MotifFunctionNone = 0;
const int MotifFunctionAll = 1;
const int MotifFunctionMove = 4;
const int MotifFunctionClose = 32;
const int MotifFunctionResize = 2;
const int MotifFunctionMinimize = 8;
const int MotifFunctionMaximize = 16;
static inline QByteArray sessionType() {
static QByteArray type = qgetenv("XDG_SESSION_TYPE");
return type;
}
static inline bool isWaylandSession() {
return sessionType().compare("wayland") == 0;
}
static inline bool isX11Session() {
return sessionType().compare("x11") == 0;
}
#endif // COMMON_H

View File

@ -0,0 +1,343 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "dbushandler.h"
#include "dbusutil.h"
#include "taskmanager.h"
#include "common.h"
#include "entry.h"
#include "windowinfok.h"
#include <DDBusSender>
#include <QtConcurrent>
DBusHandler::DBusHandler(TaskManager *taskmanager, QObject *parent)
: QObject(parent)
, m_taskmanager(taskmanager)
, m_wm(new com::deepin::wm("com.deepin.wm", "/com/deepin/wm", QDBusConnection::sessionBus(), this))
, m_wmSwitcher(new org::deepin::dde::WMSwitcher1("org.deepin.dde.WMSwitcher1", "/org/deepin/dde/WMSwitcher1", QDBusConnection::sessionBus(), this))
, m_kwaylandManager(nullptr)
, 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);
m_activeWindowMonitorKey = m_xEventMonitor->RegisterFullScreen();
connect(m_xEventMonitor, &org::deepin::dde::XEventMonitor1::ButtonRelease, this, &DBusHandler::onActiveWindowButtonRelease);
}
connect(m_launcher,static_cast<void (org::deepin::dde::Launcher1::*)(bool)>(&org::deepin::dde::Launcher1::VisibleChanged), this, [=] (const bool visible){
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()
{
m_kwaylandManager = new org::deepin::dde::kwayland1::WindowManager("org.deepin.dde.KWayland1", "/org/deepin/dde/KWayland1/WindowManager", QDBusConnection::sessionBus(), this);
connect(m_kwaylandManager, &org::deepin::dde::kwayland1::WindowManager::ActiveWindowChanged, this, &DBusHandler::handleWlActiveWindowChange);
connect(m_kwaylandManager, &org::deepin::dde::kwayland1::WindowManager::WindowCreated, this, [&] (const QString &ObjPath) {
m_taskmanager->registerWindowWayland(ObjPath);
});
connect(m_kwaylandManager, &org::deepin::dde::kwayland1::WindowManager::WindowRemove, this, [&] (const QString &ObjPath) {
m_taskmanager->unRegisterWindowWayland(ObjPath);
});
}
void DBusHandler::loadClientList()
{
if (!m_kwaylandManager)
return;
QDBusPendingReply<QVariantList> windowList = m_kwaylandManager->Windows();
QVariantList windows = windowList.value();
for (QVariant windowPath : windows)
m_taskmanager->registerWindowWayland(windowPath.toString());
}
QString DBusHandler::getCurrentWM()
{
return m_wmSwitcher->CurrentWM().value();
}
void DBusHandler::launchApp(QString desktopFile, uint32_t timestamp, QStringList files)
{
if (newStartManagerAvaliable()) {
auto objPath = desktopEscapeToObjectPath(desktopFile);
launchAppUsingApplicationManager1(QString{DDEApplicationManager1ObjectPath} + '/' + objPath, timestamp, files);
} else {
launchAppUsingApplication1Manager(desktopFile, timestamp, files);
}
}
void DBusHandler::launchAppAction(QString desktopFile, QString action, uint32_t timestamp)
{
if (newStartManagerAvaliable()) {
auto objPath = desktopEscapeToObjectPath(desktopFile);
launchAppActionUsingApplicationManager1(QString{DDEApplicationManager1ObjectPath} + '/' + objPath, action, timestamp);
} else {
launchAppActionUsingApplication1Manager(desktopFile, action, timestamp);
}
}
void DBusHandler::launchAppUsingApplication1Manager(QString desktopFile, uint32_t timestamp, QStringList files)
{
QDBusInterface interface = QDBusInterface("org.deepin.dde.Application1.Manager", "/org/deepin/dde/Application1/Manager", "org.deepin.dde.Application1.Manager");
interface.call("LaunchApp", desktopFile, timestamp, files);
}
void DBusHandler::launchAppActionUsingApplication1Manager(QString desktopFile, QString action, uint32_t timestamp)
{
QDBusInterface interface = QDBusInterface("org.deepin.dde.Application1.Manager", "/org/deepin/dde/Application1/Manager", "org.deepin.dde.Application1.Manager");
interface.call("LaunchAppAction", desktopFile, action, timestamp);
}
// 新AM启动接口
void DBusHandler::launchAppUsingApplicationManager1(QString dbusObjectPath, uint32_t timestamp, QStringList files)
{
QDBusInterface interface = QDBusInterface(ApplicationManager1DBusName, dbusObjectPath, "org.desktopspec.ApplicationManager1.Application");
interface.call("Launch", "", QStringList(), QMap<QString, QVariant>());
}
void DBusHandler::launchAppActionUsingApplicationManager1(QString dbusObjectPath, QString action, uint32_t timestamp)
{
action = action.right(action.size() - strlen(DesktopFileActionKey));
QDBusInterface interface = QDBusInterface(ApplicationManager1DBusName, dbusObjectPath, "org.desktopspec.ApplicationManager1.Application");
interface.call("Launch", action, QStringList(), QMap<QString, QVariant>());
}
void DBusHandler::markAppLaunched(const QString &filePath)
{
QDBusInterface interface = QDBusInterface("org.deepin.dde.AlRecorder1", "/org/deepin/dde/AlRecorder1", "org.deepin.dde.AlRecorder1");
interface.call("MarkLaunched", filePath);
}
bool DBusHandler::wlShowingDesktop()
{
bool ret = false;
if (m_kwaylandManager)
ret = m_kwaylandManager->IsShowingDesktop().value();
return ret;
}
uint DBusHandler::wlActiveWindow()
{
uint ret = 0;
if (m_kwaylandManager)
ret = m_kwaylandManager->ActiveWindow().value();
return ret;
}
void DBusHandler::handleWlActiveWindowChange()
{
uint activeWinInternalId = wlActiveWindow();
if (activeWinInternalId == 0)
return;
WindowInfoK *info = m_taskmanager->handleActiveWindowChangedK(activeWinInternalId);
if (info && info->getXid() != 0) {
m_taskmanager->handleActiveWindowChanged(info);
} else {
m_taskmanager->updateHideState(false);
}
}
void DBusHandler::onActiveWindowButtonRelease(int type, int x, int y, const QString &key)
{
// 当鼠标松开区域事件的时候,取消注册,同时调用激活窗口的方法来触发智能隐藏的相关信号
if (key != m_activeWindowMonitorKey)
return;
uint activeWinInternalId = wlActiveWindow();
if (activeWinInternalId == 0)
return;
WindowInfoK *info = m_taskmanager->handleActiveWindowChangedK(activeWinInternalId);
if (!info)
return;
// 如果是在当前激活窗口区域内释放的,则触发检测智能隐藏的方法
DockRect dockRect = info->getGeometry();
if (dockRect.x <= x && x <= int(dockRect.x + dockRect.w) && dockRect.y <= y && y <= int(dockRect.y + dockRect.h)) {
// 取消智能隐藏
m_taskmanager->updateHideState(false);
}
}
void DBusHandler::listenKWindowSignals(WindowInfoK *windowInfo)
{
PlasmaWindow *window = windowInfo->getPlasmaWindow();
if (!window)
return;
connect(window, &PlasmaWindow::TitleChanged, this, [=] {
windowInfo->updateTitle();
auto entry = m_taskmanager->getEntryByWindowId(windowInfo->getXid());
if (entry && entry->getCurrentWindowInfo() == windowInfo)
entry->updateName();
});
connect(window, &PlasmaWindow::IconChanged, this, [=] {
windowInfo->updateIcon();
auto entry = m_taskmanager->getEntryByWindowId(windowInfo->getXid());
if (!entry) return;
entry->updateIcon();
});
// DemandingAttention changed
connect(window, &PlasmaWindow::DemandsAttentionChanged, this, [=] {
windowInfo->updateDemandingAttention();
auto entry = m_taskmanager->getEntryByWindowId(windowInfo->getXid());
if (!entry) return;
entry->updateExportWindowInfos();
});
// Geometry changed
connect(window, &PlasmaWindow::GeometryChanged, this, [=] {
if (!windowInfo->updateGeometry()) return;
m_taskmanager->handleWindowGeometryChanged();
});
}
PlasmaWindow *DBusHandler::createPlasmaWindow(QString objPath)
{
return new PlasmaWindow("org.deepin.dde.KWayland1", objPath, QDBusConnection::sessionBus(), this);
}
/**
* @brief DBusHandler::removePlasmaWindowHandler TODO
* @param window
*/
void DBusHandler::removePlasmaWindowHandler(PlasmaWindow *window)
{
}
void DBusHandler::presentWindows(QList<uint> windows)
{
m_wm->PresentWindows(windows);
}
void DBusHandler::previewWindow(uint xid)
{
m_wm->PreviewWindow(xid);
}
void DBusHandler::cancelPreviewWindow()
{
m_wm->CancelPreviewWindow();
}
// TODO: 待优化点, 查看Bamf根据windowId获取对应应用desktopFile路径实现方式, 移除bamf依赖
QString DBusHandler::getDesktopFromWindowByBamf(XWindow windowId)
{
QDBusInterface interface0 = QDBusInterface("org.ayatana.bamf", "/org/ayatana/bamf/matcher", "org.ayatana.bamf.matcher");
QDBusReply<QString> replyApplication = interface0.call("ApplicationForXid", windowId);
QString appObjPath = replyApplication.value();
if (!replyApplication.isValid() || appObjPath.isEmpty())
return "";
QDBusInterface interface = QDBusInterface("org.ayatana.bamf", appObjPath, "org.ayatana.bamf.application");
QDBusReply<QString> replyDesktopFile = interface.call("DesktopFile");
if (replyDesktopFile.isValid())
return replyDesktopFile.value();
return "";
}
// 新的AM调用
QString DBusHandler::desktopEscapeToObjectPath(QString desktopFilePath)
{
// to desktop id
QString objectPath;
decltype(auto) desktopSuffix = ".desktop";
auto tmp = desktopFilePath.chopped(sizeof(desktopSuffix) - 1);
auto components = tmp.split(QDir::separator());
auto it = std::find(components.cbegin(), components.cend(), "applications");
if (it == components.cend()) return "_";
QString FileId;
++it;
while (it != components.cend()) {
FileId += (*(it++) + "-");
}
objectPath = FileId.chopped(1);
if (objectPath.isEmpty()) {
return "_";
}
// desktop id to objectPath
QRegularExpression re{R"([^a-zA-Z0-9])"};
auto matcher = re.globalMatch(objectPath);
while (matcher.hasNext()) {
auto replaceList = matcher.next().capturedTexts();
replaceList.removeDuplicates();
for (const auto &c : replaceList) {
auto hexStr = QString::number(static_cast<uint>(c.front().toLatin1()), 16);
objectPath.replace(c, QString{R"(_%1)"}.arg(hexStr));
}
}
return objectPath;
}
bool DBusHandler::newStartManagerAvaliable()
{
static bool isAvaiable = false;
std::call_once(m_isNewStartManagerAvaliableInited, [=](){
auto services = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
isAvaiable = std::any_of(services.begin(), services.end(), [=](const QString &name){
return name == ApplicationManager1DBusName;
});
});
return isAvaiable;
}
void DBusHandler::sendFailedDockNotification(const QString &appName)
{
QtConcurrent::run(QThreadPool::globalInstance(), [ = ] {
DDBusSender()
.service(notificationService)
.path(notificationPath)
.interface(notificationInterface)
.method(QString("Notify"))
.arg(QString("dde-control-center")) // appname
.arg(static_cast<uint>(0)) // id
.arg(QString("preferences-system")) // icon
.arg(QString(tr("failed to dock ") + appName)) // summary
.arg(QString(tr("Unrecognized application, unable to dock"))) // content
.arg(QStringList()) // actions
.arg(QVariantMap()) // hints
.arg(5000) // timeout
.call();
});
qInfo() << "unsupported app: " + appName;
}

View File

@ -0,0 +1,92 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef DBUSHANDLER_H
#define DBUSHANDLER_H
#include "com_deepin_wm.h"
#include "org_deepin_dde_launcher1.h"
#include "org_deepin_dde_wmswitcher1.h"
#include "org_deepin_dde_xeventmonitor1.h"
#include "org_deepin_dde_kwayland_windowmanager.h"
#include "org_deepin_dde_kwayland_plasmawindow.h"
#include "windowinfok.h"
#include <QObject>
#include <QDBusConnection>
#include <QDBusMessage>
class TaskManager;
// 处理DBus交互
class DBusHandler : public QObject
{
Q_OBJECT
public:
explicit DBusHandler(TaskManager *taskmanager, QObject *parent = nullptr);
/************************* KWayland/WindowManager ***************************/
void listenWaylandWMSignals();
void loadClientList();
bool wlShowingDesktop();
uint wlActiveWindow();
/************************* WMSwitcher ***************************/
QString getCurrentWM();
/************************* StartManager ***************************/
void launchApp(QString desktopFile, uint32_t timestamp, QStringList files);
void launchAppAction(QString desktopFile, QString action, uint32_t timestamp);
void launchAppUsingApplication1Manager(QString desktopFile, uint32_t timestamp, QStringList files);
void launchAppActionUsingApplication1Manager(QString desktopFile, QString action, uint32_t timestamp);
void launchAppUsingApplicationManager1(QString desktopFile, uint32_t timestamp, QStringList files);
void launchAppActionUsingApplicationManager1(QString desktopFile, QString action, uint32_t timestamp);
/************************* AlRecorder1 ***************************/
void markAppLaunched(const QString &filePath);
/************************* KWayland.PlasmaWindow ***************************/
void listenKWindowSignals(WindowInfoK *windowInfo);
void removePlasmaWindowHandler(PlasmaWindow *window);
PlasmaWindow *createPlasmaWindow(QString objPath);
/************************* WM ***************************/
void presentWindows(QList<uint> windows);
void previewWindow(uint xid);
void cancelPreviewWindow();
/************************* bamf ***************************/
// XWindow -> desktopFile
QString getDesktopFromWindowByBamf(XWindow windowId);
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);
private:
QString desktopEscapeToObjectPath(QString desktopFilePath);
private:
QString m_activeWindowMonitorKey;
TaskManager *m_taskmanager;
com::deepin::wm *m_wm;
org::deepin::dde::WMSwitcher1 *m_wmSwitcher;
org::deepin::dde::kwayland1::WindowManager *m_kwaylandManager;
org::deepin::dde::XEventMonitor1 *m_xEventMonitor;
org::deepin::dde::Launcher1 *m_launcher;
std::once_flag m_isNewStartManagerAvaliableInited;
};
#endif // DBUSHANDLER_H

View File

@ -0,0 +1,256 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "desktopinfo.h"
#include "locale.h"
#include "taskmanager/common.h"
#include "unistd.h"
#include <QDebug>
#include <algorithm>
#include <QFileInfo>
#include <QSettings>
#include <QStandardPaths>
#include <QVector>
#include <QLocale>
QStringList DesktopInfo::currentDesktops;
static QString desktopFileSuffix = ".desktop";
DesktopInfo::DesktopInfo(const QString &desktopfile)
: m_isValid(true)
, m_isInstalled(false)
{
QString desktopfilepath(desktopfile);
QFileInfo desktopFileInfo(desktopfilepath);
if (!(desktopfilepath.endsWith(desktopFileSuffix))) {
desktopfilepath = desktopfilepath + desktopFileSuffix;
desktopFileInfo.setFile(desktopfilepath);
}
auto desktopFileName = desktopFileInfo.fileName();
// 优先加载系统中的desktopfile而不是用户传递过来的
for (auto dir: QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation)) {
QString path = dir.append("/").append(desktopFileName);
if (QFile::exists(path)){
desktopFileInfo.setFile(path);
m_isInstalled = true;
}
}
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");
// check DesktopInfo valid
QStringList mainKeys = m_desktopFile->childGroups();
if (mainKeys.size() == 0)
m_isValid = false;
bool found = std::any_of(mainKeys.begin(), mainKeys.end(),
[](const auto &key) {return key == MainSection;});
if (!found)
m_isValid = false;
if (m_desktopFile->value(MainSection + '/' + KeyType).toString() != TypeApplication)
m_isValid = false;
m_name = getLocaleStr(MainSection, KeyName);
m_icon = m_desktopFile->value(MainSection + '/' + KeyIcon).toString();
m_id = getId();
}
DesktopInfo::~DesktopInfo()
{
}
QString DesktopInfo::getDesktopFilePath()
{
return m_desktopFilePath;
}
bool DesktopInfo::isValidDesktop()
{
return m_isValid;
}
bool DesktopInfo::isInstalled()
{
return m_isInstalled;
}
/** if return true, item is shown
* @brief DesktopInfo::shouldShow
* @return
*/
bool DesktopInfo::shouldShow()
{
if (getNoDisplay() || getIsHidden()) {
qDebug() << "hidden desktop file path: " << m_desktopFilePath;
return false;
}
QStringList desktopEnvs;
return getShowIn(desktopEnvs);
}
bool DesktopInfo::getNoDisplay()
{
return m_desktopFile->value(MainSection + '/' + KeyNoDisplay).toBool();
}
bool DesktopInfo::getIsHidden()
{
return m_desktopFile->value(MainSection + '/' + KeyHidden).toBool();
}
bool DesktopInfo::getShowIn(QStringList desktopEnvs)
{
#ifdef QT_DEBUG
qDebug() << "desktop file path: " << m_desktopFilePath;
#endif
if (desktopEnvs.size() == 0) {
const QString env = getenv("XDG_CURRENT_DESKTOP");
QVector<QString> desktops = env.split(":").toVector();
currentDesktops.fromVector(desktops);
desktopEnvs.fromVector(desktops);
}
QStringList onlyShowIn = m_desktopFile->value(MainSection + '/' + KeyOnlyShowIn).toStringList();
QStringList notShowIn = m_desktopFile->value(MainSection + '/' + KeyNotShowIn).toStringList();
#ifdef QT_DEBUG
qDebug() << "onlyShowIn:" << onlyShowIn <<
", notShowIn:" << notShowIn <<
", desktopEnvs:" << desktopEnvs;
#endif
for (const auto &desktop : desktopEnvs) {
bool ret = std::any_of(onlyShowIn.begin(), onlyShowIn.end(),
[&desktop](const auto &d) {return d == desktop;});
#ifdef QT_DEBUG
qInfo() << Q_FUNC_INFO << "onlyShowIn, result:" << ret;
#endif
if (ret)
return true;
ret = std::any_of(notShowIn.begin(), notShowIn.end(),
[&desktop](const auto &d) {return d == desktop;});
#ifdef QT_DEBUG
qInfo() << Q_FUNC_INFO << "notShowIn, result:" << ret;
#endif
if (ret)
return false;
}
return onlyShowIn.size() == 0;
}
QString DesktopInfo::getExecutable()
{
return m_desktopFile->value(MainSection + '/' + KeyExec).toString();
}
QList<DesktopAction> DesktopInfo::getActions()
{
QList<DesktopAction> actions;
for (const auto &mainKey : m_desktopFile->childGroups()) {
if (mainKey.startsWith(DesktopFileActionKey)) {
DesktopAction action;
action.name = getLocaleStr(mainKey, KeyName);
action.exec = m_desktopFile->value(mainKey + '/' + KeyExec).toString();
action.section = mainKey;
actions.push_back(action);
}
}
return actions;
}
// 使用appId获取DesktopInfo需检查有效性
DesktopInfo DesktopInfo::getDesktopInfoById(const QString &appId)
{
QString desktopfile(appId);
if (!desktopfile.endsWith(".desktop")) desktopfile.append(".desktop");
for (const auto & dir : QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation)) {
QString filePath = dir + desktopfile;
//检测文件有效性
if (QFile::exists(filePath)) {
return DesktopInfo(filePath);
}
}
return DesktopInfo("");
}
bool DesktopInfo::getTerminal()
{
return m_desktopFile->value(MainSection + '/' + KeyTerminal).toBool();
}
// TryExec is Path to an executable file on disk used to determine if the program is actually installed
QString DesktopInfo::getTryExec()
{
return m_desktopFile->value(MainSection + '/' + KeyTryExec).toString();
}
// 按$PATH路径查找执行文件
bool DesktopInfo::findExecutable(const QString &exec)
{
static const char *path = getenv("PATH");
static QStringList paths = QString(path).split(':');
return std::any_of(paths.begin(), paths.end(), [&exec](QString path) {return QFile::exists(path + '/' + exec);});
}
QString DesktopInfo::getGenericName()
{
return getLocaleStr(MainSection, KeyGenericName);
}
QString DesktopInfo::getName()
{
return m_name;
}
QString DesktopInfo::getIcon()
{
return m_icon;
}
QString DesktopInfo::getCommandLine()
{
return m_desktopFile->value(MainSection + '/' + KeyExec).toString();
}
QStringList DesktopInfo::getKeywords()
{
return m_desktopFile->value(MainSection + '/' + KeyKeywords).toStringList();
}
QStringList DesktopInfo::getCategories()
{
return m_desktopFile->value(MainSection + '/' + KeyCategories).toStringList();
}
QSettings *DesktopInfo::getDesktopFile()
{
return m_desktopFile.data();
}
QString DesktopInfo::getId()
{
return m_id;
}
QString DesktopInfo::getLocaleStr(const QString &section, const QString &key)
{
QString currentLanguageCode = QLocale::system().name();
QString res = m_desktopFile->value(section + '/' + key + QString("[%1]").arg(currentLanguageCode)).toString();
if (res.isEmpty()) res = m_desktopFile->value(section + '/' + key).toString();
return res;
}

View File

@ -0,0 +1,109 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef DESKTOPINFO_H
#define DESKTOPINFO_H
#include <QSettings>
#include <qscopedpointer.h>
#include <string>
#include <vector>
const QString MainSection = "Desktop Entry";
const QString KeyType = "Type";
const QString KeyVersion = "Version";
const QString KeyName = "Name";
const QString KeyGenericName = "GenericName";
const QString KeyNoDisplay = "NoDisplay";
const QString KeyComment = "Comment";
const QString KeyIcon = "Icon";
const QString KeyHidden = "Hidden";
const QString KeyOnlyShowIn = "OnlyShowIn";
const QString KeyNotShowIn = "NotShowIn";
const QString KeyTryExec = "TryExec";
const QString KeyExec = "Exec";
const QString KeyPath = "Path";
const QString KeyTerminal = "Terminal";
const QString KeyMimeType = "MimeType";
const QString KeyCategories = "Categories";
const QString KeyKeywords = "Keywords";
const QString KeyStartupNotify = "StartupNotify";
const QString KeyStartupWMClass = "StartupWMClass";
const QString KeyURL = "URL";
const QString KeyActions = "Actions";
const QString KeyDBusActivatable = "DBusActivatable";
const QString TypeApplication = "Application";
const QString TypeLink = "Link";
const QString TypeDirectory = "Directory";
typedef struct DesktopAction
{
DesktopAction()
: section("")
, name("")
, exec("")
{
}
QString section;
QString name;
QString exec;
} DesktopAction;
// 应用Desktop信息类
class DesktopInfo {
public:
explicit DesktopInfo(const QString &desktopfile);
~DesktopInfo();
static bool isDesktopAction(const QString &name);
static DesktopInfo getDesktopInfoById(const QString &appId);
bool shouldShow();
bool getIsHidden();
bool isInstalled();
bool getTerminal();
bool getNoDisplay();
bool isExecutableOk();
bool isValidDesktop();
bool getShowIn(QStringList desktopEnvs);
void setDesktopOverrideExec(const QString &execStr);
QString getId();
QString getName();
QString getIcon();
QString getExecutable();
QString getGenericName();
QString getCommandLine();
QString getDesktopFilePath();
QStringList getKeywords();
QStringList getCategories();
QList<DesktopAction> getActions();
QSettings *getDesktopFile();
private:
bool findExecutable(const QString &exec);
QString getTryExec();
QString getLocaleStr(const QString &section, const QString &key);
private:
static QStringList currentDesktops;
bool m_isValid;
bool m_isInstalled;
QString m_id;
QString m_name;
QString m_icon;
QString m_desktopFilePath;
// Desktopfile ini format
QScopedPointer<QSettings> m_desktopFile;
};
#endif // DESKTOPINFO_H

View File

@ -0,0 +1,351 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "entries.h"
#include "taskmanager.h"
#include "docksettings.h"
#include "taskmanager/windowinfobase.h"
#include <QList>
#include <algorithm>
#include <iterator>
Entries::Entries(TaskManager *_taskmanager)
: m_taskmanager(_taskmanager)
{
}
QVector<Entry *> Entries::filterDockedEntries()
{
QVector<Entry *> ret;
for (auto entry : m_items) {
if (entry->isValid() && entry->getIsDocked()) ret.push_back(entry);
}
return ret;
}
Entry *Entries::getByInnerId(QString innerId)
{
Entry *ret = nullptr;
for (auto &entry : m_items) {
if (entry->getInnerId() == innerId)
ret = entry;
}
return ret;
}
void Entries::append(Entry *entry)
{
insert(entry, -1);
}
void Entries::insert(Entry *entry, int index)
{
// 如果当前应用在列表中存在(通常是该应用为最近打开应用但是关闭了最近打开应用的接口或者当前为高效模式)
if (m_items.contains(entry))
m_items.removeOne(entry);
if (index < 0 || index >= m_items.size()) {
// append
index = m_items.size();
m_items.push_back(entry);
} else {
// insert
m_items.insert(index, entry);
}
insertCb(entry, index);
}
void Entries::remove(Entry *entry)
{
for (auto iter = m_items.begin(); iter != m_items.end();) {
if ((*iter)->getId() == entry->getId()) {
iter = m_items.erase(iter);
} else {
iter++;
}
}
removeCb(entry);
entry->deleteLater();
}
void Entries::move(int oldIndex, int newIndex)
{
if (oldIndex == newIndex || oldIndex < 0 || newIndex < 0 || oldIndex >= m_items.size() || newIndex >= m_items.size())
return;
m_items.swapItemsAt(oldIndex, newIndex);
}
Entry *Entries::getByWindowPid(int pid)
{
Entry *ret = nullptr;
for (auto &entry : m_items) {
if (entry->getWindowInfoByPid(pid)) {
ret = entry;
break;
}
}
return ret;
}
QStringList Entries::getEntryIDs()
{
QStringList list;
if (m_taskmanager->getDisplayMode() == DisplayMode::Fashion
&& DockSettings::instance()->showRecent()) {
for (Entry *item : m_items) list << item->getId();
} else {
// 如果是高效模式或者没有开启显示最近应用的功能,那么未驻留并且没有子窗口的就不显示
// 换句话说,只显示已经驻留或者有子窗口的应用
for (Entry *item : m_items) {
if (item->getIsDocked() || item->hasWindow())
list << item->getId();
}
}
return list;
}
Entry *Entries::getByWindowId(XWindow windowId)
{
Entry *ret = nullptr;
for (auto &entry : m_items) {
if (entry->getWindowInfoByWinId(windowId)) {
ret = entry;
break;
}
}
return ret;
}
Entry *Entries::getByDesktopFilePath(const QString &filePath)
{
Entry *ret = nullptr;
for (auto &entry : m_items) {
qDebug() << entry->getName();
if (entry->getFileName() == filePath) {
ret = entry;
break;
}
}
return ret;
}
QList<Entry*> Entries::getEntries()
{
QList<Entry*> list;
if (static_cast<DisplayMode>(m_taskmanager->getDisplayMode()) == DisplayMode::Fashion
&& DockSettings::instance()->showRecent()) {
for (Entry *item : m_items)
list << item;
} else {
// 如果是高效模式或者没有开启显示最近应用的功能,那么未驻留并且没有子窗口的就不显示
// 换句话说,只显示已经驻留或者有子窗口的应用
for (Entry *item : m_items) {
if (!item->getIsDocked() && !item->hasWindow())
continue;
list << item;
}
}
return list;
}
Entry *Entries::getDockedEntryByDesktopFile(const QString &desktopFile)
{
QFileInfo desktopFileInfo(desktopFile);
Entry *ret = nullptr;
for (auto entry : filterDockedEntries()) {
if ((entry->isValid()) && desktopFileInfo.canonicalFilePath() == entry->getFileName()) {
ret = entry;
break;
}
}
return ret;
}
QString Entries::queryWindowIdentifyMethod(XWindow windowId)
{
QString ret;
for (auto entry : m_items) {
auto window = entry->getWindowInfoByWinId(windowId);
if (window) {
auto app = window->getAppInfo();
ret = app ? app->getIdentifyMethod() : "Failed";
break;
}
}
return ret;
}
void Entries::handleActiveWindowChanged(XWindow activeWindId)
{
for (auto entry : m_items) {
auto windowInfo = entry->getWindowInfoByWinId(activeWindId);
if (windowInfo) {
entry->setPropIsActive(true);
entry->setCurrentWindowInfo(windowInfo);
entry->updateName();
entry->updateIcon();
} else {
entry->setPropIsActive(false);
}
}
}
void Entries::updateEntriesMenu()
{
for (auto entry : m_items) {
entry->updateMenu();
}
}
const QList<Entry *> Entries::unDockedEntries() const
{
QList<Entry *> entrys;
for (Entry *entry : m_items) {
if (!entry->isValid() || entry->getIsDocked())
continue;
entrys << entry;
}
return entrys;
}
void Entries::moveEntryToLast(Entry *entry)
{
if (m_items.contains(entry)) {
m_items.removeOne(entry);
m_items << entry;
}
}
void Entries::insertCb(Entry *entry, int index)
{
if (entry->getIsDocked() || entry->hasWindow() ||
((m_taskmanager->getDisplayMode() == DisplayMode::Fashion) && DockSettings::instance()->showRecent())){
Q_EMIT m_taskmanager->entryAdded(entry, index);
}
}
void Entries::removeCb(Entry *entry)
{
Q_EMIT m_taskmanager->entryRemoved(entry->getId());
}
bool Entries::shouldInRecent()
{
// 如果当前移除的应用是未驻留应用则判断未驻留应用的数量是否小于等于3则让其始终显示
QList<Entry *> unDocktrys;
for (Entry *entry : m_items) {
if (entry->isValid() && !entry->getIsDocked())
unDocktrys << entry;
}
// 如果当前未驻留应用的数量小于3个则认为后续的应用应该显示到最近打开应用
return (unDocktrys.size() <= MAX_UNOPEN_RECENT_COUNT);
}
void Entries::removeLastRecent()
{
// 先查找最近使用的应用,删除没有使用的
int unDockCount = 0;
QList<Entry *> unDockEntrys;
QList<Entry *> removeEntrys;
for (Entry *entry : m_items) {
if (entry->getIsDocked())
continue;
// 此处只移除没有子窗口的图标
if (!entry->hasWindow()) {
if (!entry->isValid())
removeEntrys << entry; // 如果应用已经被卸载,那么需要删除
else
unDockEntrys << entry;
}
unDockCount++;
}
if (unDockCount >= MAX_UNOPEN_RECENT_COUNT && unDockEntrys.size() > 0) {
// 只有当最近使用区域的图标大于等于某个数值3的时候并且存在没有子窗口的Entry那么就移除该Entry
Entry *entry = unDockEntrys[0];
removeEntrys << entry;
}
for (Entry *entry : removeEntrys) {
m_items.removeOne(entry);
removeCb(entry);
entry->deleteLater();
}
}
void Entries::setDisplayMode(DisplayMode displayMode)
{
if (!DockSettings::instance()->showRecent())
return;
// 如果从时尚模式变成高效模式,对列表中所有的没有打开窗口的应用发送移除信号
if (displayMode == DisplayMode::Efficient) {
for (Entry *entry : m_items) {
entry->updateMode();
if (!entry->getIsDocked() && !entry->hasWindow())
Q_EMIT m_taskmanager->entryRemoved(entry->getId());
}
} else {
// 如果从高效模式变成时尚模式,列表中所有的未驻留且不存在打开窗口的应用认为是最近打开应用,发送新增信号
for (Entry *entry : m_items) {
entry->updateMode();
if (!entry->getIsDocked() && !entry->hasWindow()) {
// QString objPath = entry->path();
int index = m_items.indexOf(entry);
Q_EMIT m_taskmanager->entryAdded(entry, index);
qDebug() << entry->getName();
}
}
}
}
void Entries::updateShowRecent()
{
// 高效模式无需做任何操作
if (static_cast<DisplayMode>(m_taskmanager->getDisplayMode()) != DisplayMode::Fashion)
return;
bool showRecent = DockSettings::instance()->showRecent();
if (showRecent) {
// 如果显示最近打开应用,则发送新增信号
for (Entry *entry : m_items) {
// 已经驻留的或者有子窗口的本来就在任务栏上面,无需发送信号
entry->updateMode();
if (entry->getIsDocked() || entry->hasWindow())
continue;
// QString objPath = entry->path();
int index = m_items.indexOf(entry);
Q_EMIT m_taskmanager->entryAdded(entry, index);
}
} else {
// 如果是隐藏最近打开的应用,则发送移除的信号
for (Entry *entry : m_items) {
// 已经驻留的或者有子窗口的本来就在任务栏上面,无需发送信号
entry->updateMode();
if (entry->getIsDocked() || entry->hasWindow())
continue;
Q_EMIT m_taskmanager->entryRemoved(entry->getId());
}
}
}

View File

@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef ENTRIES_H
#define ENTRIES_H
#include "entry.h"
#include "constants.h"
#include "taskmanager/windowinfobase.h"
#include <QVector>
#include <QWeakPointer>
#include <qlist.h>
#define MAX_UNOPEN_RECENT_COUNT 3
class TaskManager;
// 所有应用管理类
class Entries
{
public:
Entries(TaskManager *_taskmanager);
const QList<Entry *> unDockedEntries() const;
bool shouldInRecent();
void removeLastRecent();
void updateShowRecent();
void updateEntriesMenu();
void append(Entry *entry);
void remove(Entry *entry);
void moveEntryToLast(Entry *entry);
void insert(Entry *entry, int index);
void move(int oldIndex, int newIndex);
void setDisplayMode(Dock::DisplayMode displayMode);
void handleActiveWindowChanged(XWindow activeWindId);
QString queryWindowIdentifyMethod(XWindow windowId);
QStringList getEntryIDs();
Entry *getByWindowPid(int pid);
Entry *getByInnerId(QString innerId);
Entry *getByWindowId(XWindow windowId);
Entry *getByDesktopFilePath(const QString &filePath);
Entry *getDockedEntryByDesktopFile(const QString &desktopFile);
QList<Entry*> getEntries();
QVector<Entry *> filterDockedEntries();
private:
void insertCb(Entry *entry, int index);
void removeCb(Entry *entry);
private:
QList<Entry *> m_items;
TaskManager *m_taskmanager;
};
#endif // ENTRIES_H

883
frame/taskmanager/entry.cpp Normal file
View File

@ -0,0 +1,883 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "entry.h"
#include "docksettings.h"
#include "xcbutils.h"
#include "taskmanager.h"
#include "processinfo.h"
#include "windowinfomap.h"
#include <QDebug>
#include <QDBusInterface>
#include <algorithm>
#include <signal.h>
#define XCB XCBUtils::instance()
Entry::Entry(TaskManager *_taskmanager, AppInfo *_app, QString _innerId, QObject *parent)
: QObject(parent)
, m_isActive(false)
, m_isDocked(false)
, m_winIconPreferred(false)
, m_innerId(_innerId)
, m_adapterEntry(nullptr)
, m_taskmanager(_taskmanager)
, m_current(nullptr)
, m_currentWindow(0)
{
setAppInfo(_app);
m_id = m_taskmanager->allocEntryId();
m_mode = getCurrentMode();
m_name = getName();
m_icon = getIcon();
}
Entry::~Entry()
{
for (auto winInfo : m_windowInfoMap) {
if (winInfo) winInfo->deleteLater();
}
m_windowInfoMap.clear();
}
bool Entry::isValid()
{
// desktopfile 无效时且没有窗口时该entry是无效的
// 虽然也就是desktop是无效时但是当前存在窗口该entry也是有效的。
return m_isValid || m_current;
}
QString Entry::getId() const
{
return m_id;
}
QString Entry::getName()
{
QString ret = m_current ? m_current->getDisplayName() : QString();
if (m_appInfo.isNull()) return ret;
ret = m_appInfo->getName();
return ret;
}
void Entry::updateName()
{
setPropName(getName());
}
QString Entry::getIcon()
{
QString ret;
if (hasWindow()) {
if (!m_current) {
return ret;
}
// has window && current not nullptr
if (m_winIconPreferred) {
// try current window icon first
ret = m_current->getIcon();
if (ret.size() > 0) {
return ret;
}
}
if (m_appInfo) {
m_icon = m_appInfo->getIcon();
if (m_icon.size() > 0) {
return m_icon;
}
}
return m_current->getIcon();
}
if (m_appInfo) {
// no window
return m_appInfo->getIcon();
}
return ret;
}
QString Entry::getInnerId()
{
return m_innerId;
}
void Entry::setInnerId(QString _innerId)
{
qDebug() << "setting innerID from: " << m_innerId << " to: " << _innerId;
m_innerId = _innerId;
}
QString Entry::getFileName()
{
return m_appInfo.isNull() ? QString() : m_appInfo->getFileName();
}
AppInfo *Entry::getAppInfo()
{
return m_appInfo.data();
}
void Entry::setAppInfo(AppInfo *appinfo)
{
if (m_appInfo.data() == appinfo || appinfo == nullptr) {
return;
}
m_appInfo.reset(appinfo);
m_isValid = appinfo->isValidApp();
m_winIconPreferred = !appinfo;
setPropDesktopFile(appinfo ? appinfo->getFileName(): "");
if (!m_winIconPreferred) {
QString id = m_appInfo->getId();
auto perferredApps = m_taskmanager->getWinIconPreferredApps();
if (perferredApps.contains(id)|| appinfo->getIcon().size() == 0) {
m_winIconPreferred = true;
return;
}
}
}
bool Entry::getIsDocked() const
{
return m_isDocked;
}
void Entry::setIsDocked(bool value)
{
if (value != m_isDocked) {
m_isDocked = value;
Q_EMIT isDockedChanged(value);
}
}
void Entry::setMenu(AppMenu *_menu)
{
_menu->setDirtyStatus(true);
m_appMenu.reset(_menu);
Q_EMIT menuChanged(m_appMenu->getMenuJsonStr());
}
void Entry::updateMenu()
{
qInfo() <<"Entry: updateMenu";
AppMenu *appMenu = new AppMenu();
appMenu->appendItem(getMenuItemLaunch());
for (auto &item :getMenuItemDesktopActions())
appMenu->appendItem(item);
if (hasWindow())
appMenu->appendItem(getMenuItemAllWindows());
// menu item dock or undock
qInfo() << "entry " << m_id << " docked? " << m_isDocked;
appMenu->appendItem(m_isDocked? getMenuItemUndock(): getMenuItemDock());
if (hasWindow()) {
if (m_taskmanager->getForceQuitAppStatus() != ForceQuitAppMode::Disabled) {
appMenu->appendItem(m_appInfo && m_appInfo->getIdentifyMethod() == "Andriod" ?
getMenuItemForceQuitAndroid() : getMenuItemForceQuit());
}
if (getAllowedCloseWindows().size() > 0)
appMenu->appendItem(getMenuItemCloseAll());
}
setMenu(appMenu);
}
void Entry::updateIcon()
{
setPropIcon(getIcon());
}
int Entry::getCurrentMode()
{
// 只要当前应用是已经驻留的应用则让其显示为Normal
if (getIsDocked())
return ENTRY_NORMAL;
// 对于未驻留的应用则做如下处理
if (m_taskmanager->getDisplayMode() == DisplayMode::Efficient) {
// 高效模式下只有存在子窗口的则让其为nornal没有子窗口的一般不让其显示
return hasWindow() ? ENTRY_NORMAL : ENTRY_NONE;
}
// 时尚模式下对未驻留应用做如下处理
// 如果开启了最近打开应用的功能则显示到最近打开区域ENTRY_RECENT
if (DockSettings::instance()->showRecent())
return ENTRY_RECENT;
// 未开启最近使用应用的功能,如果有子窗口,则显示成通用的(ENTRY_NORMAL),如果没有子窗口,则不显示(ENTRY_NONE)
return hasWindow() ? ENTRY_NORMAL : ENTRY_NONE;
}
void Entry::updateMode()
{
int currentMode = getCurrentMode();
if (m_mode != currentMode) {
m_mode = currentMode;
Q_EMIT modeChanged(m_mode);
}
}
void Entry::forceUpdateIcon()
{
m_icon = getIcon();
Q_EMIT iconChanged(m_icon);
}
void Entry::updateIsActive()
{
bool isActive = false;
auto activeWin = m_taskmanager->getActiveWindow();
if (activeWin) {
// 判断活跃窗口是否属于当前应用
isActive = m_windowInfoMap.find(activeWin->getXid()) != m_windowInfoMap.end();
}
setPropIsActive(isActive);
}
WindowInfoBase *Entry::getWindowInfoByPid(int pid)
{
for (const auto &windowInfo : m_windowInfoMap) {
if (windowInfo->getPid() == pid)
return windowInfo;
}
return nullptr;
}
WindowInfoBase *Entry::getWindowInfoByWinId(XWindow windowId)
{
if (m_windowInfoMap.find(windowId) != m_windowInfoMap.end())
return m_windowInfoMap[windowId];
return nullptr;
}
void Entry::setPropIcon(QString value)
{
if (value != m_icon) {
m_icon = value;
Q_EMIT iconChanged(value);
}
}
void Entry::setPropName(QString value)
{
if (value != m_name) {
m_name = value;
Q_EMIT nameChanged(value);
}
}
void Entry::setPropIsActive(bool active)
{
if (m_isActive != active) {
m_isActive = active;
Q_EMIT isActiveChanged(active);
}
}
void Entry::setCurrentWindowInfo(WindowInfoBase *windowInfo)
{
m_current = windowInfo;
setPropCurrentWindow(m_current ? m_current->getXid() : 0);
}
void Entry::setPropCurrentWindow(XWindow value)
{
if (value != m_currentWindow) {
m_currentWindow = value;
Q_EMIT currentWindowChanged(value);
}
}
WindowInfoBase *Entry::getCurrentWindowInfo()
{
return m_current;
}
/**
* @brief Entry::findNextLeader
* @return
*/
WindowInfoBase *Entry::findNextLeader()
{
auto xids = m_windowInfoMap.keys();
std::sort(xids.begin(), xids.end());
XWindow curWinId = m_current->getXid();
int index = xids.indexOf(curWinId);
if (index < 0)
return nullptr;
// 如果当前窗口是最大, 返回xids[0], 否则返回xids[index + 1]
int nextIndex = 0;
if (index < xids.size() - 1)
nextIndex = index + 1;
return m_windowInfoMap[xids[nextIndex]];
}
QString Entry::getExec()
{
if (!m_current)
return "";
ProcessInfo *process = m_current->getProcess();
return process->getExe();
}
QString Entry::getCmdLine()
{
QString ret;
if (!m_current) return ret;
ProcessInfo *process = m_current->getProcess();
for (auto i : process->getCmdLine()) ret += i + " ";
return ret;
}
bool Entry::hasWindow()
{
return m_windowInfoMap.size() > 0;
}
/**
* @brief Entry::updateExportWindowInfos
*/
void Entry::updateExportWindowInfos()
{
WindowInfoMap infos;
for (auto info : m_windowInfoMap) {
WindowInfo winInfo;
XWindow xid = info->getXid();
winInfo.title = info->getTitle();
winInfo.attention = info->isDemandingAttention();
winInfo.uuid = info->uuid();
infos[xid] = winInfo;
}
bool changed = true;
if (infos.size() == m_exportWindowInfos.size()) {
changed = false;
for (auto iter = infos.begin(); iter != infos.end(); iter++) {
XWindow xid = iter.key();
if (infos[xid].title != m_exportWindowInfos[xid].title ||
infos[xid].attention != m_exportWindowInfos[xid].attention ||
infos[xid].uuid != m_exportWindowInfos[xid].uuid) {
changed = true;
break;
}
}
}
if (changed) {
Q_EMIT windowInfosChanged(infos);
}
// 更新导出的窗口信息
m_exportWindowInfos = infos;
}
// 分离窗口, 返回是否需要从任务栏remove
bool Entry::detachWindow(WindowInfoBase *info)
{
info->setEntry(nullptr);
XWindow winId = info->getXid();
if (m_windowInfoMap.contains(winId)) {
m_windowInfoMap.remove(winId);
info->deleteLater();
}
if (m_windowInfoMap.isEmpty()) {
if (!m_isDocked) {
// 既无窗口也非驻留应用,并且不是最近打开,无需在任务栏显示
return true;
}
Q_EMIT windowInfosChanged(WindowInfoMap());
setCurrentWindowInfo(nullptr);
} else {
for (auto window : m_windowInfoMap) {
if (window) { // 选择第一个窗口作为当前窗口
setCurrentWindowInfo(window);
break;
}
}
}
updateExportWindowInfos();
updateIcon();
updateMenu();
return false;
}
bool Entry::isShowOnDock() const
{
// 当前应用显示图标的条件是
// 如果该图标已经固定在任务栏上,则始终显示
if (getIsDocked())
return true;
// 1.时尚模式下,如果开启了显示最近使用,则不管是否有子窗口,都在任务栏上显示
// 如果没有开启显示最近使用,则只显示有子窗口的
if (m_taskmanager->getDisplayMode() == DisplayMode::Fashion)
return (DockSettings::instance()->showRecent() || m_exportWindowInfos.size() > 0);
// 2.高效模式下,只有该应用有打开窗口才显示
return m_exportWindowInfos.size() > 0;
}
bool Entry::attachWindow(WindowInfoBase *info)
{
XWindow winId = info->getXid();
qInfo() << "attatchWindow: window id:" << winId;
info->setEntry(this);
if (m_windowInfoMap.find(winId) != m_windowInfoMap.end()) {
qInfo() << "attachWindow: window " << winId << " is already attached";
return false;
}
bool lastShowOnDock = isShowOnDock();
m_windowInfoMap[winId] = info;
updateExportWindowInfos();
updateIsActive();
if (!m_current) {
// from no window to has window
setCurrentWindowInfo(info);
}
updateIcon();
updateMenu();
if (!lastShowOnDock && isShowOnDock()) {
// 新打开的窗口始终显示到最后
Q_EMIT m_taskmanager->entryAdded(this, -1);
}
return true;
}
void Entry::launchApp(uint32_t timestamp)
{
if (m_appInfo)
m_taskmanager->launchApp(m_appInfo->getFileName(), timestamp, QStringList());
}
bool Entry::containsWindow(XWindow xid)
{
return m_windowInfoMap.find(xid) != m_windowInfoMap.end();
}
// 处理菜单项
void Entry::handleMenuItem(uint32_t timestamp, QString itemId)
{
m_appMenu->handleAction(timestamp, itemId);
}
// 处理拖拽事件
void Entry::handleDragDrop(uint32_t timestamp, QStringList files)
{
m_taskmanager->launchApp(m_appInfo->getFileName(), timestamp, files);
}
// 驻留
void Entry::requestDock(bool dockToEnd)
{
if (m_taskmanager->dockEntry(this, dockToEnd)) {
m_taskmanager->saveDockedApps();
}
}
// 取消驻留
void Entry::requestUndock(bool dockToEnd)
{
m_taskmanager->undockEntry(this, dockToEnd);
}
void Entry::newInstance(uint32_t timestamp)
{
QStringList files;
m_taskmanager->launchApp(m_appInfo->getFileName(), timestamp, files);
}
// 检查应用窗口分离、合并状态
void Entry::check()
{
QList<WindowInfoBase *> windows = m_windowInfoMap.values();
for (WindowInfoBase *window : windows) {
m_taskmanager->attachOrDetachWindow(window);
}
}
// 强制退出
void Entry::forceQuit()
{
QMap<int, QVector<WindowInfoBase*>> pidWinInfoMap;
QList<WindowInfoBase *> windows = m_windowInfoMap.values();
for (WindowInfoBase *window : windows) {
int pid = window->getPid();
if (pid != 0) {
pidWinInfoMap[pid].push_back(window);
} else {
window->killClient();
}
}
for (auto iter = pidWinInfoMap.begin(); iter != pidWinInfoMap.end(); iter++) {
if (!killProcess(iter.key())) { // kill pid
for (auto &info : iter.value()) { // kill window
info->killClient();
}
}
}
// 所有的窗口已经退出后清空m_windowInfoMap内容
m_windowInfoMap.clear();
// 退出所有的进程后,及时更新当前剩余的窗口数量
updateExportWindowInfos();
m_taskmanager->removeEntryFromDock(this);
}
void Entry::presentWindows()
{
QList<uint> windows = m_windowInfoMap.keys();
m_taskmanager->presentWindows(windows);
}
/**
* @brief Entry::active
* @param timestamp
*/
void Entry::active(uint32_t timestamp)
{
if (m_taskmanager->getHideMode() == HideMode::SmartHide) {
m_taskmanager->setPropHideState(HideState::Show);
m_taskmanager->updateHideState(false);
}
// 无窗口则直接启动
if (!hasWindow()) {
launchApp(timestamp);
return;
}
if (!m_current) {
qWarning() << "active: current window is nullptr";
return;
}
WindowInfoBase *winInfo = m_current;
if (m_taskmanager->isWaylandEnv()) {
// wayland环境
if (!m_taskmanager->isActiveWindow(winInfo)) {
winInfo->activate();
} else {
bool showing = m_taskmanager->isShowingDesktop();
if (showing || winInfo->isMinimized()) {
winInfo->activate();
} else if (m_windowInfoMap.size() == 1) {
winInfo->minimize();
} else {
WindowInfoBase *nextWin = findNextLeader();
if (nextWin) {
nextWin->activate();
}
}
}
} else {
// X11环境
XWindow xid = winInfo->getXid();
WindowInfoBase *activeWin = m_taskmanager->getActiveWindow();
if (activeWin && xid != activeWin->getXid()) {
m_taskmanager->doActiveWindow(xid);
} else {
bool found = false;
XWindow hiddenAtom = XCB->getAtom("_NET_WM_STATE_HIDDEN");
for (auto state : XCB->getWMState(xid)) {
if (hiddenAtom == state) {
found = true;
break;
}
}
if (found) {
// 激活隐藏窗口
m_taskmanager->doActiveWindow(xid);
} else if (m_windowInfoMap.size() == 1) {
// 窗口图标化
XCB->minimizeWindow(xid);
} else if (m_taskmanager->getActiveWindow() && m_taskmanager->getActiveWindow()->getXid() == xid) {
WindowInfoBase *nextWin = findNextLeader();
if (nextWin) {
nextWin->activate();
}
}
}
}
}
void Entry::activeWindow(quint32 winId)
{
if (m_taskmanager->isWaylandEnv()) {
if (!m_windowInfoMap.contains(winId))
return;
WindowInfoBase *winInfo = m_windowInfoMap[winId];
if (m_taskmanager->isActiveWindow(winInfo)) {
bool showing = m_taskmanager->isShowingDesktop();
if (showing || winInfo->isMinimized()) {
winInfo->activate();
} else if (m_windowInfoMap.size() == 1) {
winInfo->minimize();
} else {
WindowInfoBase *nextWin = findNextLeader();
if (nextWin) {
nextWin->activate();
}
}
} else {
winInfo->activate();
}
} else {
m_taskmanager->doActiveWindow(winId);
}
}
int Entry::mode()
{
return m_mode;
}
XWindow Entry::getCurrentWindow()
{
return m_currentWindow;
}
QString Entry::getDesktopFile()
{
return m_desktopFile;
}
bool Entry::getIsActive() const
{
return m_isActive;
}
QString Entry::getMenu() const
{
return m_appMenu->getMenuJsonStr();
}
QVector<XWindow> Entry::getAllowedClosedWindowIds()
{
QVector<XWindow> ret;
for (auto iter = m_windowInfoMap.begin(); iter != m_windowInfoMap.end(); iter++) {
WindowInfoBase *info = iter.value();
if (info && info->allowClose())
ret.push_back(iter.key());
}
return ret;
}
WindowInfoMap Entry::getExportWindowInfos()
{
return m_exportWindowInfos;
}
QVector<WindowInfoBase *> Entry::getAllowedCloseWindows()
{
QVector<WindowInfoBase *> ret;
for (auto iter = m_windowInfoMap.begin(); iter != m_windowInfoMap.end(); iter++) {
WindowInfoBase *info = iter.value();
if (info && info->allowClose()) {
ret.push_back(info);
}
}
return ret;
}
QVector<AppMenuItem> Entry::getMenuItemDesktopActions()
{
QVector<AppMenuItem> ret;
if (!m_appInfo) {
return ret;
}
for (auto action : m_appInfo->getActions()) {
AppMenuAction fn = [=](uint32_t timestamp) {
qInfo() << "do MenuItem: " << action.name;
m_taskmanager->launchAppAction(m_appInfo->getFileName(), action.section, timestamp);
};
AppMenuItem item;
item.text = action.name;
item.action = fn;
item.isActive = true;
ret.push_back(item);
}
return ret;
}
AppMenuItem Entry::getMenuItemLaunch()
{
QString itemName;
if (hasWindow()) {
itemName = getName();
} else {
itemName = tr("Open");
}
AppMenuAction fn = [this](uint32_t timestamp) {
qInfo() << "do MenuItem: Open";
this->launchApp(timestamp);
};
AppMenuItem item;
item.text = itemName;
item.action = fn;
item.isActive = true;
return item;
}
AppMenuItem Entry::getMenuItemCloseAll()
{
AppMenuAction fn = [this](uint32_t timestamp) {
qInfo() << "do MenuItem: Close All";
auto winInfos = getAllowedCloseWindows();
// 根据创建时间从大到小排序, 方便后续关闭窗口
for (int i = 0; i < winInfos.size() - 1; i++) {
for (int j = i + 1; j < winInfos.size(); j++) {
if (winInfos[i]->getCreatedTime() < winInfos[j]->getCreatedTime()) {
auto info = winInfos[i];
winInfos[i] = winInfos[j];
winInfos[j] = info;
}
}
}
for (auto info : winInfos) {
qInfo() << "close WindowId " << info->getXid();
info->close(timestamp);
}
// 关闭窗口后,主动刷新事件
XCB->flush();
};
AppMenuItem item;
item.text = tr("Close All");
item.action = fn;
item.isActive = true;
return item;
}
AppMenuItem Entry::getMenuItemForceQuit()
{
bool active = m_taskmanager->getForceQuitAppStatus() != ForceQuitAppMode::Deactivated;
AppMenuAction fn = [this](uint32_t) {
qInfo() << "do MenuItem: Force Quit";
forceQuit();
};
AppMenuItem item;
item.text = tr("Force Quit");
item.action = fn;
item.isActive = active;
return item;
}
//dock栏上Android程序的Force Quit功能
AppMenuItem Entry::getMenuItemForceQuitAndroid()
{
bool active = m_taskmanager->getForceQuitAppStatus() != ForceQuitAppMode::Deactivated;
auto allowedCloseWindows = getAllowedCloseWindows();
AppMenuAction fn = [](uint32_t){};
if (allowedCloseWindows.size() > 0) {
qInfo() << "do MenuItem: Force Quit";
AppMenuAction fn = [&](uint32_t timestamp) {
for (auto info : allowedCloseWindows) {
info->close(timestamp);
}
};
}
AppMenuItem item;
item.text = tr("Force Quit");
item.action = fn;
item.isActive = active;
return item;
}
AppMenuItem Entry::getMenuItemDock()
{
AppMenuItem item;
item.text = tr("Dock");
item.action = [this](uint32_t) {
qInfo() << "do MenuItem: Dock";
requestDock(true);
};
item.isActive = true;
return item;
}
AppMenuItem Entry::getMenuItemUndock()
{
AppMenuItem item;
item.text = tr("Undock");
item.action = [this](uint32_t) {
qInfo() << "do MenuItem: Undock";
requestUndock(true);
};
item.isActive = true;
return item;
}
AppMenuItem Entry::getMenuItemAllWindows()
{
AppMenuItem item;
item.text = tr("All Windows");
item.action = [this](uint32_t) {
qInfo() << "do MenuItem: All Windows";
presentWindows();
};
item.isActive = true;
item.hint = 1;
return item;
}
bool Entry::killProcess(int pid)
{
return !kill(pid, SIGTERM);
}
bool Entry::setPropDesktopFile(QString value)
{
if (value != m_desktopFile) {
m_desktopFile = value;
Q_EMIT desktopFileChanged(value);
return true;
}
return false;
}

156
frame/taskmanager/entry.h Normal file
View File

@ -0,0 +1,156 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef ENTRY_H
#define ENTRY_H
#include "appinfo.h"
#include "appmenu.h"
#include "windowinfomap.h"
#include "windowinfobase.h"
#include <QMap>
#include <QVector>
#include <QObject>
#include <qscopedpointer.h>
#define ENTRY_NONE 0
#define ENTRY_NORMAL 1
#define ENTRY_RECENT 2
// 单个应用类
class TaskManager;
class DBusAdaptorEntry;
class WindowInfo;
typedef QMap<quint32, WindowInfo> WindowInfoMap;
class Entry: public QObject
{
Q_OBJECT
public:
Entry(TaskManager *_taskmanager, AppInfo *_app, QString _innerId, QObject *parent = nullptr);
~Entry();
void updateName();
void updateMenu();
void updateIcon();
void updateMode();
void updateIsActive();
void forceUpdateIcon();
void updateExportWindowInfos();
void launchApp(uint32_t timestamp);
void setIsDocked(bool value);
void setMenu(AppMenu *_menu);
void setPropIcon(QString value);
void setPropName(QString value);
void setPropIsActive(bool active);
void setInnerId(QString _innerId);
void setAppInfo(AppInfo *appinfo);
void setPropCurrentWindow(XWindow value);
void setCurrentWindowInfo(WindowInfoBase *windowInfo);
void check();
void forceQuit();
void presentWindows();
void active(uint32_t timestamp);
void activeWindow(quint32 winId);
void newInstance(uint32_t timestamp);
void requestDock(bool dockToEnd = false);
void requestUndock(bool dockToEnd = false);
void handleMenuItem(uint32_t timestamp, QString itemId);
void handleDragDrop(uint32_t timestamp, QStringList files);
bool containsWindow(XWindow xid);
bool detachWindow(WindowInfoBase *info);
bool attachWindow(WindowInfoBase *info);
bool getIsDocked() const;
bool getIsActive() const;
QString getId() const;
QString getMenu() const;
bool isValid();
bool hasWindow();
int mode();
QString getName();
QString getIcon();
QString getInnerId();
QString getFileName();
QString getDesktopFile();
QString getExec();
QString getCmdLine();
XWindow getCurrentWindow();
AppInfo *getAppInfo();
WindowInfoBase *findNextLeader();
WindowInfoBase *getCurrentWindowInfo();
WindowInfoBase *getWindowInfoByPid(int pid);
WindowInfoBase *getWindowInfoByWinId(XWindow windowId);
WindowInfoMap getExportWindowInfos();
QVector<XWindow> getAllowedClosedWindowIds();
public Q_SLOTS:
QVector<WindowInfoBase *> getAllowedCloseWindows();
Q_SIGNALS:
void modeChanged(int);
void isActiveChanged(bool);
void isDockedChanged(bool);
void menuChanged(QString);
void iconChanged(QString);
void nameChanged(QString);
void desktopFileChanged(QString);
void currentWindowChanged(uint32_t);
void windowInfosChanged(const WindowInfoMap&);
private:
// 右键菜单项
bool killProcess(int pid);
bool setPropDesktopFile(QString value);
bool isShowOnDock() const;
int getCurrentMode();
AppMenuItem getMenuItemLaunch();
AppMenuItem getMenuItemCloseAll();
AppMenuItem getMenuItemForceQuit();
AppMenuItem getMenuItemDock();
AppMenuItem getMenuItemUndock();
AppMenuItem getMenuItemAllWindows();
AppMenuItem getMenuItemForceQuitAndroid();
QVector<AppMenuItem> getMenuItemDesktopActions();
private:
bool m_isActive;
bool m_isValid;
bool m_isDocked;
bool m_winIconPreferred;
int m_mode;
QString m_id;
QString m_name;
QString m_icon;
QString m_innerId;
QString m_desktopFile;
DBusAdaptorEntry *m_adapterEntry;
TaskManager *m_taskmanager;
WindowInfoMap m_exportWindowInfos; // 该应用导出的窗口属性
WindowInfoBase *m_current; // 当前窗口
XWindow m_currentWindow; //当前窗口Id
QScopedPointer<AppInfo> m_appInfo;
QScopedPointer<AppMenu> m_appMenu;
QMap<XWindow, WindowInfoBase *> m_windowInfoMap; // 该应用所有窗口
};
#endif // ENTRY_H

View File

@ -0,0 +1,214 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "processinfo.h"
#include <string>
#include <fstream>
#include <unistd.h>
#include <QDir>
#include <QDebug>
#include <QFileInfo>
ProcessInfo::ProcessInfo(int pid)
: m_pid(pid)
, m_ppid(0)
{
if (pid == 0)
return;
m_exe = getExe();
m_cwd = getCwd();
m_cmdLine = getCmdLine();
getStatus();
// 部分root进程在/proc文件系统查找不到exe、cwd、cmdline信息
if (m_exe.isEmpty() || m_cwd.isEmpty() || m_cmdLine.size() == 0) {
m_isValid = false;
return;
}
// args
qInfo() << "ProcessInfo: exe=" << m_exe << " cwd=" << m_cwd << " cmdLine=" << (m_cmdLine[0].isEmpty() ? " " : m_cmdLine[0]);
auto verifyExe = [](QString exe, QString cwd, QString firstArg){
if (firstArg.size() == 0) return false;
QFileInfo info(firstArg);
if (info.completeBaseName() == firstArg) return true;
if (!QDir::isAbsolutePath(firstArg))
firstArg = cwd + firstArg;
return exe == firstArg;
};
if (!m_cmdLine[0].isEmpty()) {
if (!verifyExe(m_exe, m_cwd, m_cmdLine[0])) {
auto parts = m_cmdLine[0].split(' ');
// try again
if (verifyExe(m_exe, m_cwd, parts[0])) {
m_args.append(parts.mid(1, parts.size() - 1));
m_args.append(m_cmdLine.mid(1, m_cmdLine.size() - 1));
}
} else {
m_args.append(m_cmdLine.mid(1, m_cmdLine.size() - 1));
}
}
}
ProcessInfo::ProcessInfo(QStringList cmd)
: m_hasPid(false)
, m_isValid(true)
{
if (cmd.size() == 0) {
m_isValid = false;
return;
}
m_cmdLine = cmd;
m_exe = cmd[0];
m_args.append(cmd.mid(1, cmd.size() - 1));
}
ProcessInfo::~ProcessInfo()
{
}
QString ProcessInfo::getEnv(const QString &key)
{
if (m_environ.size() == 0) getEnviron();
return m_environ[key];
}
Status ProcessInfo::getStatus()
{
if (!m_status.empty()){
return m_status;
}
QString statusFile = getFile("status");
std::ifstream fs(statusFile.toStdString());
if (!fs.is_open()) {
return m_status;
}
std::string tmp = "";
while (std::getline(fs, tmp)) {
auto pos = tmp.find_first_of(':');
if (pos == std::string::npos) {
continue;
}
QString value;
if (pos + 1 < tmp.length()) {
value = QString::fromStdString(tmp.substr(pos + 1));
}
m_status[QString::fromStdString(tmp.substr(0, pos))] = value;
}
return m_status;
}
QStringList ProcessInfo::getCmdLine()
{
if (m_cmdLine.size() == 0) {
QString cmdlineFile = getFile("cmdline");
m_cmdLine = readFile(cmdlineFile);
}
return m_cmdLine;
}
QStringList ProcessInfo::getArgs()
{
return m_args;
}
int ProcessInfo::getPid()
{
return m_pid;
}
int ProcessInfo::getPpid()
{
if (m_ppid == 0) {
if (m_status.find("PPid") != m_status.end()) {
m_ppid = std::stoi(m_status["PPid"].toStdString());
}
}
return m_ppid;
}
bool ProcessInfo::initWithPid()
{
return m_hasPid;
}
bool ProcessInfo::isValid()
{
return m_isValid;
}
QString ProcessInfo::getExe()
{
if (m_exe.isEmpty()) {
QString cmdLineFile = getFile("exe");
QFileInfo path(cmdLineFile);
m_exe = path.canonicalFilePath();
}
return m_exe;
}
bool ProcessInfo::isExist()
{
QString procDir = "/proc/" + QString(m_pid);
return QFile::exists(procDir);
}
QStringList ProcessInfo::readFile(const QString &filePath)
{
QStringList ret;
std::ifstream fs(filePath.toStdString());
if (!fs.is_open()) {
return ret;
}
std::string tmp;
while (std::getline(fs, tmp, '\0')) {
ret.append(QString::fromStdString(tmp));
}
return ret;
}
QString ProcessInfo::getFile(const QString &file)
{
return QString("/proc/").append(QString::number(m_pid).append('/').append(file));
}
QString ProcessInfo::getCwd()
{
if (m_cwd.isEmpty()) {
QString cwdFile = getFile("cwd");
QFileInfo path(cwdFile);
m_cwd = path.canonicalFilePath();
}
return m_cwd;
}
QMap<QString, QString> ProcessInfo::getEnviron()
{
if (m_environ.size() == 0) {
QString envFile = getFile("environ");
QStringList contents = readFile(envFile);
for (auto line : contents){
int index = line.indexOf('=');
m_environ.insert(line.left(index), line.right(line.size() - index - 1));
}
}
return m_environ;
}

View File

@ -0,0 +1,59 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef PROCESSINFO_H
#define PROCESSINFO_H
#include <QMap>
#include <QVector>
#include <QStringList>
typedef QMap<QString, QString> Status;
// 进程信息
class ProcessInfo
{
public:
explicit ProcessInfo(int pid);
explicit ProcessInfo(QStringList cmd);
virtual ~ProcessInfo();
bool isValid();
bool initWithPid();
int getPid();
int getPpid();
QString getExe();
QString getCwd();
Status getStatus();
QString getEnv(const QString &key);
QStringList getArgs();
QStringList getCmdLine();
QMap<QString, QString> getEnviron();
private:
bool isExist();
QString getJoinedExeArgs();
QString getFile(const QString &file);
QStringList readFile(const QString &filePath);
private:
int m_pid;
int m_ppid;
bool m_hasPid;
bool m_isValid;
Status m_status;
QString m_exe;
QString m_cwd;
QStringList m_args;
QStringList m_cmdLine;
QVector<int> m_uids;
QMap<QString, QString> m_environ;
};
#endif // PROCESSINFO_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,199 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef DOCK_H
#define DOCK_H
#include "docksettings.h"
#include "entries.h"
#include "org_deepin_dde_kwayland_plasmawindow.h"
#include <QStringList>
#include <QTimer>
#include <QMutex>
#include <QObject>
class WindowIdentify;
class DBusHandler;
class WaylandManager;
class X11Manager;
class WindowInfoK;
class WindowInfoX;
using PlasmaWindow = org::deepin::dde::kwayland1::PlasmaWindow;
// 任务管理
class TaskManager : public QObject
{
Q_OBJECT
public:
static inline TaskManager *instance() {
static TaskManager instance;
return &instance;
}
// 将Entry dock在任务栏上
bool dockEntry(Entry *entry, bool moveToEnd = false);
void undockEntry(Entry *entry, bool moveToEnd = false);
QString allocEntryId();
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);
void attachWindow(WindowInfoBase *info);
void detachWindow(WindowInfoBase *info);
void launchApp(const QString desktopFile, uint32_t timestamp, QStringList files);
void launchAppAction(const QString desktopFile, QString action, uint32_t timestamp);
bool is3DWM();
bool isWaylandEnv();
WindowInfoK *handleActiveWindowChangedK(uint activeWin);
void saveDockedApps();
void removeAppEntry(Entry *entry);
void handleWindowGeometryChanged();
Entry *getEntryByWindowId(XWindow windowId);
QString getDesktopFromWindowByBamf(XWindow windowId);
void registerWindowWayland(const QString &objPath);
void unRegisterWindowWayland(const QString &objPath);
bool isShowingDesktop();
AppInfo *identifyWindow(WindowInfoBase *winInfo, QString &innerId);
void markAppLaunched(AppInfo *appInfo);
ForceQuitAppMode getForceQuitAppStatus();
QVector<QString> getWinIconPreferredApps();
void handleLauncherItemDeleted(QString itemPath);
void handleLauncherItemUpdated(QString itemPath);
QRect getFrontendWindowRect();
DisplayMode getDisplayMode();
void setDisplayMode(int mode);
QStringList getDockedApps();
QList<Entry*> getEntries();
HideMode getHideMode();
void setHideMode(HideMode mode);
HideState getHideState();
void setHideState(HideState state);
uint getHideTimeout();
void setHideTimeout(uint timeout);
uint getIconSize();
void setIconSize(uint size);
int getPosition();
void setPosition(int position);
uint windowMargin() const;
uint getShowTimeout();
void setShowTimeout(uint timeout);
uint getWindowSizeEfficient();
void setWindowSizeEfficient(uint size);
uint getWindowSizeFashion();
void setWindowSizeFashion(uint size);
/******************************** dbus handler ****************************/
PlasmaWindow *createPlasmaWindow(QString objPath);
void listenKWindowSignals(WindowInfoK *windowInfo);
void removePlasmaWindowHandler(PlasmaWindow *window);
void presentWindows(QList<uint> windows);
HideMode getDockHideMode();
bool isActiveWindow(const WindowInfoBase *win);
WindowInfoBase *getActiveWindow();
void doActiveWindow(XWindow xid);
QList<XWindow> getClientList();
void setClientList(QList<XWindow> value);
void closeWindow(XWindow windowId);
void MinimizeWindow(XWindow windowId);
QStringList getEntryIDs();
void setFrontendWindowRect(int32_t x, int32_t y, uint width, uint height);
bool isDocked(const QString desktopFile);
bool requestDock(QString desktopFile, int index);
bool requestUndock(QString desktopFile);
void setShowMultiWindow(bool visible);
bool showMultiWindow() const;
void moveEntry(int oldIndex, int newIndex);
bool isOnDock(QString desktopFile);
QString queryWindowIdentifyMethod(XWindow windowId);
QStringList getDockedAppsDesktopFiles();
QString getPluginSettings();
void setPluginSettings(QString jsonStr);
void mergePluginSettings(QString jsonStr);
void removePluginSettings(QString pluginName, QStringList settingkeys);
void removeEntryFromDock(Entry *entry);
void previewWindow(uint xid);
void cancelPreviewWindow();
bool preventDockAutoHide() const;
Q_SIGNALS:
void serviceRestarted();
void entryAdded(const Entry* entry, int index);
void entryRemoved(QString id);
void hideStateChanged(int);
void frontendWindowRectChanged(const QRect &dockRect);
void showRecentChanged(bool);
void showMultiWindowChanged(bool);
void windowMarginChanged(uint);
public Q_SLOTS:
void updateHideState(bool delay);
void handleActiveWindowChanged(WindowInfoBase *info);
void smartHideModeTimerExpired();
void attachOrDetachWindow(WindowInfoBase *info);
private:
explicit TaskManager(QObject *parent = nullptr);
~TaskManager();
void initSettings();
void initEntries();
void loadAppInfos();
void initClientList();
WindowInfoX *findWindowByXidX(XWindow xid);
WindowInfoK *findWindowByXidK(XWindow xid);
bool isWindowDockOverlapX(XWindow xid);
bool hasInterSectionX(const Geometry &windowRect, QRect dockRect);
bool isWindowDockOverlapK(WindowInfoBase *info);
bool hasInterSectionK(const DockRect &windowRect, QRect dockRect);
Entry *getDockedEntryByDesktopFile(const QString &desktopFile);
bool shouldHideOnSmartHideMode();
QVector<XWindow> getActiveWinGroup(XWindow xid);
void updateRecentApps();
private:
void onShowRecentChanged(bool visible);
void onShowMultiWindowChanged(bool visible);
private:
bool m_isWayland; // 判断是否为wayland环境
bool m_showRecent;
bool m_showMultiWindow;
int m_entriesSum; // 累计打开的应用数量
QString m_wmName; // 窗管名称
HideState m_hideState; // 记录任务栏隐藏状态
QRect m_frontendWindowRect; // 前端任务栏大小, 用于智能隐藏时判断窗口是否重合
ForceQuitAppMode m_forceQuitAppStatus; // 强制退出应用状态
bool m_ddeLauncherVisible;
bool m_trayGridWidgetVisible;
bool m_popupVisible;
Entries *m_entries; // 所有应用实例
X11Manager *m_x11Manager; // X11窗口管理
WaylandManager *m_waylandManager; // wayland窗口管理
WindowIdentify *m_windowIdentify; // 窗口识别
QTimer *m_smartHideTimer; // 任务栏智能隐藏定时器
DBusHandler *m_dbusHandler; // 处理dbus交互
WindowInfoBase *m_activeWindow;// 记录当前活跃窗口信息
WindowInfoBase *m_activeWindowOld;// 记录前一个活跃窗口信息
QList<XWindow> m_clientList; // 所有窗口
};
#endif // TASKMANAGER_H

View File

@ -0,0 +1,119 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "waylandmanager.h"
#include "taskmanager.h"
#include "taskmanager/entry.h"
#include "xcbutils.h"
#define XCB XCBUtils::instance()
WaylandManager::WaylandManager(TaskManager *_taskmanager, QObject *parent)
: QObject(parent)
, m_taskmanager(_taskmanager)
, m_mutex(QMutex(QMutex::NonRecursive))
{
}
/**
* @brief WaylandManager::registerWindow
* @param objPath
*/
void WaylandManager::registerWindow(const QString &objPath)
{
qInfo() << "registerWindow: " << objPath;
if (findWindowByObjPath(objPath))
return;
PlasmaWindow *plasmaWindow = m_taskmanager->createPlasmaWindow(objPath);
if (!plasmaWindow) {
qWarning() << "registerWindowWayland: createPlasmaWindow failed";
return;
}
if (!plasmaWindow->IsValid() || !plasmaWindow->isValid()) {
qWarning() << "PlasmaWindow is not valid:" << objPath;
plasmaWindow->deleteLater();
return;
}
QString appId = plasmaWindow->AppId();
QStringList list {"dde-dock", "dde-launcher", "dde-clipboard", "dde-osd", "dde-polkit-agent", "dde-simple-egl", "dmcs", "dde-lock"};
if (list.indexOf(appId) >= 0 || appId.startsWith("No such object path")) {
plasmaWindow->deleteLater();
return;
}
XWindow winId = XCB->allocId(); // XCB中未发现释放XID接口
XWindow realId = plasmaWindow->WindowId();
if (realId)
winId = realId;
WindowInfoK *winInfo = new WindowInfoK(plasmaWindow, winId);
m_taskmanager->listenKWindowSignals(winInfo);
insertWindow(objPath, winInfo);
m_taskmanager->attachOrDetachWindow(winInfo);
if (winId) {
m_windowInfoMap[winId] = winInfo;
}
}
// 取消注册窗口
void WaylandManager::unRegisterWindow(const QString &objPath)
{
qInfo() << "unRegisterWindow: " << objPath;
WindowInfoK *winInfo = findWindowByObjPath(objPath);
if (!winInfo)
return;
m_taskmanager->removePlasmaWindowHandler(winInfo->getPlasmaWindow());
m_taskmanager->detachWindow(winInfo);
deleteWindow(objPath);
}
WindowInfoK *WaylandManager::findWindowById(uint activeWin)
{
QMutexLocker locker(&m_mutex);
for (auto iter = m_kWinInfos.begin(); iter != m_kWinInfos.end(); iter++) {
if (iter.value()->getInnerId() == QString::number(activeWin)) {
return iter.value();
}
}
return nullptr;
}
WindowInfoK *WaylandManager::findWindowByXid(XWindow xid)
{
WindowInfoK *winInfo = nullptr;
for (auto iter = m_kWinInfos.begin(); iter != m_kWinInfos.end(); iter++) {
if (iter.value()->getXid() == xid) {
winInfo = iter.value();
break;
}
}
return winInfo;
}
WindowInfoK *WaylandManager::findWindowByObjPath(QString objPath)
{
if (m_kWinInfos.find(objPath) == m_kWinInfos.end())
return nullptr;
return m_kWinInfos[objPath];
}
void WaylandManager::insertWindow(QString objPath, WindowInfoK *windowInfo)
{
QMutexLocker locker(&m_mutex);
m_kWinInfos[objPath] = windowInfo;
}
void WaylandManager::deleteWindow(QString objPath)
{
m_kWinInfos.remove(objPath);
}

View File

@ -0,0 +1,40 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef WAYLANDMANAGER_H
#define WAYLANDMANAGER_H
#include "taskmanager/entry.h"
#include "windowinfok.h"
#include <QObject>
#include <QMap>
#include <QMutex>
class TaskManager;
// 管理wayland窗口
class WaylandManager : public QObject
{
Q_OBJECT
public:
explicit WaylandManager(TaskManager *_taskmanager, QObject *parent = nullptr);
void registerWindow(const QString &objPath);
void unRegisterWindow(const QString &objPath);
WindowInfoK *findWindowById(uint activeWin);
WindowInfoK *findWindowByXid(XWindow xid);
WindowInfoK *findWindowByObjPath(QString objPath);
void insertWindow(QString objPath, WindowInfoK *windowInfo);
void deleteWindow(QString objPath);
private:
TaskManager *m_taskmanager;
QMap<QString, WindowInfoK *> m_kWinInfos; // dbusObjectPath -> kwayland window Info
QMap<XWindow, WindowInfoK *> m_windowInfoMap;
QMutex m_mutex;
};
#endif // WAYLANDMANAGER_H

View File

@ -0,0 +1,246 @@
[
{
"ret": "id=jftp",
"rules": [
[
"exec",
"=:java"
],
[
"arg",
"c:jftp.jar"
]
]
},
{
"ret": "env",
"rules": [
[
"wmi",
"=:dman"
],
[
"wmc",
"=:DManual"
]
]
},
{
"ret": "env",
"rules": [
[
"wmi",
"r:\\.exe$"
],
[
"wmi",
"=!iesetup.exe"
],
[
"wmc",
"=:Wine"
]
]
},
{
"ret": "id=netbeans",
"rules": [
[
"wmc",
"c:netbeans"
],
[
"exec",
"=:java"
],
[
"arg",
"c:netbeans"
]
]
},
{
"ret": "id=jabref",
"rules": [
[
"wmc",
"c:jabref"
],
[
"exec",
"=:java"
],
[
"arg",
"c:jabref"
]
]
},
{
"ret": "env",
"rules": [
[
"wmi",
"=:player"
],
[
"wmc",
"c:genymotion"
]
]
},
{
"ret": "id=xdemineur",
"rules": [
[
"wmi",
"c:xdemineur"
],
[
"exec",
"=:xdemineur"
]
]
},
{
"ret": "id=minecraft",
"rules": [
[
"wmi",
"c:minecraft"
],
[
"wmc",
"c:minecraft"
]
]
},
{
"ret": "id=steam",
"rules": [
[
"hasPid",
"=:f"
],
[
"wmi",
"=:"
],
[
"wmc",
"=:"
],
[
"wmn",
"e:steam"
]
]
},
{
"ret": "id=mintdrivers",
"rules": [
[
"wmi",
"e:mintdrivers.py"
],
[
"wmc",
"e:mintdrivers.py"
]
]
},
{
"ret": "id=google-earth",
"rules": [
[
"wmi",
"c:googleearth"
],
[
"wmc",
"c:googleearth"
]
]
},
{
"ret": "id=the-powder-toy",
"rules": [
[
"wmi",
"e:powder"
],
[
"wmc",
"e:powder"
],
[
"hasPid",
"=:t"
]
]
},
{
"ret": "id=cn.google.chrome",
"rules": [
[
"wmi",
"e:google-chrome"
],
[
"wmc",
"e:google-chrome"
]
]
},
{
"ret": "id=ganttproject",
"rules": [
[
"wmi",
"R:^sun-awt-X11"
],
[
"exec",
"=:java"
],
[
"env.CLASSPATH",
"c:ganttproject"
],
[
"arg",
"c:ganttproject"
]
]
},
{
"ret": "id=gdevelop",
"rules": [
[
"wmi",
"c:gdevelop"
],
[
"wmc",
"c:gdevelop"
],
[
"exec",
"=:gdevelop"
]
]
},
{
"ret": "id=apps.com.wechat.web",
"rules": [
[
"wmi",
"e:wx2.qq.com"
],
[
"wmc",
"e:google-chrome"
]
]
}
]

View File

@ -0,0 +1,551 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#include "windowidentify.h"
#include "common.h"
#include "appinfo.h"
#include "taskmanager.h"
#include "processinfo.h"
#include "taskmanager/desktopinfo.h"
#include "xcbutils.h"
#include "bamfdesktop.h"
#include <QDebug>
#include <QThread>
#include <QDBusConnection>
#define XCB XCBUtils::instance()
static QMap<QString, QString> crxAppIdMap = {
{"crx_onfalgmmmaighfmjgegnamdjmhpjpgpi", "apps.com.aiqiyi"},
{"crx_gfhkopakpiiaeocgofdpcpjpdiglpkjl", "apps.cn.kugou.hd"},
{"crx_gaoopbnflngfkoobibfgbhobdeiipcgh", "apps.cn.kuwo.kwmusic"},
{"crx_jajaphleehpmpblokgighfjneejapnok", "apps.com.evernote"},
{"crx_ebhffdbfjilfhahiinoijchmlceailfn", "apps.com.letv"},
{"crx_almpoflgiciaanepplakjdkiaijmklld", "apps.com.tongyong.xxbox"},
{"crx_heaphplipeblmpflpdcedfllmbehonfo", "apps.com.peashooter"},
{"crx_dbngidmdhcooejaggjiochbafiaefndn", "apps.com.rovio.angrybirdsseasons"},
{"crx_chfeacahlaknlmjhiagghobhkollfhip", "apps.com.sina.weibo"},
{"crx_cpbmecbkmjjfemjiekledmejoakfkpec", "apps.com.openapp"},
{"crx_lalomppgkdieklbppclocckjpibnlpjc", "apps.com.baidutieba"},
{"crx_gejbkhjjmicgnhcdpgpggboldigfhgli", "apps.com.zhuishushenqi"},
{"crx_gglenfcpioacendmikabbkecnfpanegk", "apps.com.duokan"},
{"crx_nkmmgdfgabhefacpfdabadjfnpffhpio", "apps.com.zhihu.daily"},
{"crx_ajkogonhhcighbinfgcgnjiadodpdicb", "apps.com.netease.newsreader"},
{"crx_hgggjnaaklhemplabjhgpodlcnndhppo", "apps.com.baidu.music.pad"},
{"crx_ebmgfebnlgilhandilnbmgadajhkkmob", "apps.cn.ibuka"},
{"crx_nolebplcbgieabkblgiaacdpgehlopag", "apps.com.tianqitong"},
{"crx_maghncnmccfbmkekccpmkjjfcmdnnlip", "apps.com.youjoy.strugglelandlord"},
{"crx_heliimhfjgfabpgfecgdhackhelmocic", "apps.cn.emoney"},
{"crx_jkgmneeafmgjillhgmjbaipnakfiidpm", "apps.com.instagram"},
{"crx_cdbkhmfmikobpndfhiphdbkjklbmnakg", "apps.com.easymindmap"},
{"crx_djflcciklfljleibeinjmjdnmenkciab", "apps.com.lgj.thunderbattle"},
{"crx_ffdgbolnndgeflkapnmoefhjhkeilfff", "apps.com.qianlong"},
{"crx_fmpniepgiofckbfgahajldgoelogdoap", "apps.com.windhd"},
{"crx_dokjmallmkihbgefmladclcdcinjlnpj", "apps.com.youdao.hanyu"},
{"crx_dicimeimfmbfcklbjdpnlmjgegcfilhm", "apps.com.ibookstar"},
{"crx_cokkcjnpjfffianjbpjbcgjefningkjm", "apps.com.yidianzixun"},
{"crx_ehflkacdpmeehailmcknlnkmjalehdah", "apps.com.xplane"},
{"crx_iedokjbbjejfinokgifgecmboncmkbhb", "apps.com.wedevote"},
{"crx_eaefcagiihjpndconigdpdmcbpcamaok", "apps.com.tongwei.blockbreaker"},
{"crx_mkjjfibpccammnliaalefmlekiiikikj", "apps.com.dayima"},
{"crx_gflkpppiigdigkemnjlonilmglokliol", "apps.com.cookpad"},
{"crx_jfhpkchgedddadekfeganigbenbfaohe", "apps.com.issuu"},
{"crx_ggkmfnbkldhmkehabgcbnmlccfbnoldo", "apps.bible.cbol"},
{"crx_phlhkholfcljapmcidanddmhpcphlfng", "apps.com.kanjian.radio"},
{"crx_bjgfcighhaahojkibojkdmpdihhcehfm", "apps.de.danoeh.antennapod"},
{"crx_kldipknjommdfkifomkmcpbcnpmcnbfi", "apps.com.asoftmurmur"},
{"crx_jfhlegimcipljdcionjbipealofoncmd", "apps.com.tencentnews"},
{"crx_aikgmfkpmmclmpooohngmcdimgcocoaj", "apps.com.tonghuashun"},
{"crx_ifimglalpdeoaffjmmihoofapmpflkad", "apps.com.letv.lecloud.disk"},
{"crx_pllcekmbablpiogkinogefpdjkmgicbp", "apps.com.hwadzanebook"},
{"crx_ohcknkkbjmgdfcejpbmhjbohnepcagkc", "apps.com.douban.radio"},
};
WindowIdentify::WindowIdentify(TaskManager *_taskmanager, QObject *parent)
: QObject(parent)
, m_taskmanager(_taskmanager)
{
m_identifyWindowFuns << qMakePair(QString("Android") , &identifyWindowAndroid);
m_identifyWindowFuns << qMakePair(QString("PidEnv"), &identifyWindowByPidEnv);
m_identifyWindowFuns << qMakePair(QString("CmdlineTurboBooster"), &identifyWindowByCmdlineTurboBooster);
m_identifyWindowFuns << qMakePair(QString("Cmdline-XWalk"), &identifyWindowByCmdlineXWalk);
m_identifyWindowFuns << qMakePair(QString("FlatpakAppID"), &identifyWindowByFlatpakAppID);
m_identifyWindowFuns << qMakePair(QString("CrxId"), &identifyWindowByCrxId);
m_identifyWindowFuns << qMakePair(QString("Rule"), &identifyWindowByRule);
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)
{
if (!winInfo)
return nullptr;
qInfo() << "identifyWindow: window id " << winInfo->getXid() << " innerId " << winInfo->getInnerId();
if (winInfo->getWindowType() == "X11")
return identifyWindowX11(static_cast<WindowInfoX *>(winInfo), innerId);
if (winInfo->getWindowType() == "Wayland")
return identifyWindowWayland(static_cast<WindowInfoK *>(winInfo), innerId);
return nullptr;
}
AppInfo *WindowIdentify::identifyWindowX11(WindowInfoX *winInfo, QString &innerId)
{
AppInfo *appInfo = nullptr;
if (winInfo->getInnerId().isEmpty()) {
qInfo() << "identifyWindowX11: window innerId is empty";
return appInfo;
}
for (auto iter = m_identifyWindowFuns.begin(); iter != m_identifyWindowFuns.end(); iter++) {
QString name = iter->first;
IdentifyFunc func = iter->second;
qInfo() << "identifyWindowX11: try " << name;
appInfo = func(m_taskmanager, winInfo, innerId);
if (appInfo) { // TODO: if name == "Pid", appInfo may by nullptr
// 识别成功
qInfo() << "identify Window by " << name << " innerId " << appInfo->getInnerId() << " success!";
AppInfo *fixedAppInfo = fixAutostartAppInfo(appInfo->getFileName());
if (fixedAppInfo) {
delete appInfo;
appInfo = fixedAppInfo;
appInfo->setIdentifyMethod(name + "+FixAutostart");
innerId = appInfo->getInnerId();
} else {
appInfo->setIdentifyMethod(name);
}
return appInfo;
}
}
qInfo() << "identifyWindowX11: failed";
// 如果识别窗口失败则该app的entryInnerId使用当前窗口的innerId
innerId = winInfo->getInnerId();
return appInfo;
}
AppInfo *WindowIdentify::identifyWindowWayland(WindowInfoK *winInfo, QString &innerId)
{
// TODO: 对桌面调起的文管应用做规避处理需要在此处添加因为初始化时appId和title为空
if (winInfo->getAppId() == "dde-desktop" && m_taskmanager->shouldShowOnDock(winInfo)) {
winInfo->setAppId("dde-file-manager");
}
QString appId = winInfo->getAppId();
if (appId.isEmpty()) {
QString title = winInfo->getTitle();
// TODO: 对于appId为空的情况使用title过滤此项修改针对浏览器下载窗口
}
// 先使用appId获取appInfo,如果不能成功获取再使用GIO_LAUNCHED_DESKTOP_FILE环境变量获取
AppInfo *appInfo = new AppInfo(appId);
if (!appInfo->isValidApp() && winInfo->getProcess()) {
ProcessInfo *process = winInfo->getProcess();
QString desktopFilePath = process->getEnv("GIO_LAUNCHED_DESKTOP_FILE");
if ((desktopFilePath.endsWith(".desktop"))) {
appInfo = new AppInfo(desktopFilePath);
}
}
// autoStart
if (appInfo->isValidApp()) {
AppInfo *fixedAppInfo = fixAutostartAppInfo(appInfo->getFileName());
if (fixedAppInfo) {
delete appInfo;
appInfo = fixedAppInfo;
appInfo->setIdentifyMethod("FixAutostart");
}
}
if (appInfo)
innerId = appInfo->getInnerId();
return appInfo;
}
AppInfo *WindowIdentify::identifyWindowAndroid(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
AppInfo *ret = nullptr;
int32_t androidId = getAndroidUengineId(winInfo->getXid());
QString androidName = getAndroidUengineName(winInfo->getXid());
if (androidId != -1 && androidName != "") {
QString desktopPath = "/usr/share/applications/uengine." + androidName + ".desktop";
DesktopInfo desktopInfo(desktopPath);
if (!desktopInfo.isValidDesktop()) {
qInfo() << "identifyWindowAndroid: not exist DesktopFile " << desktopPath;
return ret;
}
ret = new AppInfo(desktopInfo);
ret->setIdentifyMethod("Android");
innerId = ret->getInnerId();
}
return ret;
}
AppInfo *WindowIdentify::identifyWindowByPidEnv(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
AppInfo *ret = nullptr;
int pid = winInfo->getPid();
auto process = winInfo->getProcess();
qInfo() << "identifyWindowByPidEnv: pid=" << pid << " WindowId=" << winInfo->getXid();
if (pid == 0 || !process) {
return ret;
}
QString launchedDesktopFile = process->getEnv("GIO_LAUNCHED_DESKTOP_FILE");
QString launchedDesktopFilePidStr = process->getEnv("GIO_LAUNCHED_DESKTOP_FILE_PID");
int launchedDesktopFilePid = launchedDesktopFilePidStr.toInt();
qInfo() << "launchedDesktopFilePid=" << launchedDesktopFilePid << " launchedDesktopFile=" << launchedDesktopFile;
if (launchedDesktopFile.isEmpty()) {
return ret;
}
auto pidIsSh = [](int pid) -> bool {
ProcessInfo parentProcess(pid);
auto parentCmdLine = parentProcess.getCmdLine();
if (parentCmdLine.size() <= 0) {
return false;
}
qInfo() << "ppid equal" << "parentCmdLine[0]:" << parentCmdLine[0];
QString cmd0 = parentCmdLine[0];
int pos = cmd0.lastIndexOf('/');
if (pos > 0)
cmd0 = cmd0.remove(0, pos + 1);
if (cmd0 == "sh" || cmd0 == "bash"){
return true;
}
return false;
};
auto processInLinglong = [](ProcessInfo* const process) -> bool {
for (ProcessInfo p(process->getPpid()); p.getPid() != 0; p = ProcessInfo(p.getPpid())) {
if (!p.getCmdLine().size()){
qWarning() << "Failed to get command line of" << p.getPid() << " SKIP it.";
continue;
}
if (p.getCmdLine()[0].indexOf("ll-box") != -1) {
qDebug() << "process ID" << process->getPid() << "is in linglong container,"
<<"ll-box PID" << p.getPid();
return true;
}
}
return false;
};
// 以下几种情况下,才能信任环境变量 GIO_LAUNCHED_DESKTOP_FILE。
if (pid == launchedDesktopFilePid || // 当窗口pid和launchedDesktopFilePid相同时
( process->getPpid() &&
process->getPpid() == launchedDesktopFilePid &&
pidIsSh(process->getPpid())
) || // 当窗口的进程的父进程id即ppid和launchedDesktopFilePid相同并且该父进程是sh或bash时。
processInLinglong(process) // 当窗口pid在玲珑容器中
) {
ret = new AppInfo(launchedDesktopFile);
innerId = ret->getInnerId();
}
return ret;
}
AppInfo *WindowIdentify::identifyWindowByCmdlineTurboBooster(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
AppInfo *ret = nullptr;
int pid = winInfo->getPid();
ProcessInfo *process = winInfo->getProcess();
if (pid != 0 && process) {
auto cmdline = process->getCmdLine();
if (cmdline.size() > 0) {
QString desktopFile;
if (cmdline[0].startsWith(".desktop")) {
desktopFile = cmdline[0];
} else if (QString(cmdline[0]).contains("/applications/")) {
QFileInfo fileInfo(cmdline[0]);
QString path = fileInfo.path();
QString base = fileInfo.completeBaseName();
QDir dir(path);
QStringList files = dir.entryList(QDir::Files);
for (auto f : files) {
if (f.contains(path + "/" + base + ".desktop")) {
desktopFile = f;
break;
}
}
qInfo() << "identifyWindowByCmdlineTurboBooster: desktopFile is " << desktopFile;
if (!desktopFile.isEmpty()) {
ret = new AppInfo(desktopFile);
innerId = ret->getInnerId();
}
}
}
}
return ret;
}
AppInfo *WindowIdentify::identifyWindowByCmdlineXWalk(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
qInfo() << "identifyWindowByCmdlineXWalk: windowId=" << winInfo->getXid();
AppInfo *ret = nullptr;
do {
auto process = winInfo->getProcess();
if (!process || !winInfo->getPid())
break;
QString exe = process->getExe();
QFileInfo file(exe);
QString exeBase = file.completeBaseName();
auto args = process->getArgs();
if (exe != "xwalk" || args.size() == 0)
break;
QString lastArg = args[args.size() - 1];
file.setFile(lastArg);
if (file.completeBaseName() == "manifest.json") {
auto strs = lastArg.split("/");
if (strs.size() > 3 && strs[strs.size() - 2].size() > 0) { // appId为 strs倒数第二个字符串
ret = new AppInfo(strs[strs.size() - 2]);
innerId = ret->getInnerId();
break;
}
}
qInfo() << "identifyWindowByCmdlineXWalk: failed";
} while (0);
return ret;
}
AppInfo *WindowIdentify::identifyWindowByFlatpakAppID(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
AppInfo *ret = nullptr;
QString flatpak = winInfo->getFlatpakAppId();
qInfo() << "identifyWindowByFlatpakAppID: flatpak:" << flatpak;
if (flatpak.startsWith("app/")) {
auto parts = flatpak.split("/");
if (parts.size() > 0) {
QString appId = parts[1];
ret = new AppInfo(appId);
innerId = ret->getInnerId();
}
}
return ret;
}
AppInfo *WindowIdentify::identifyWindowByCrxId(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
AppInfo *ret = nullptr;
WMClass wmClass = XCB->getWMClass(winInfo->getXid());
QString className, instanceName;
className.append(wmClass.className.c_str());
instanceName.append(wmClass.instanceName.c_str());
if (className.toLower() == "chromium-browser" && instanceName.toLower().startsWith("crx_")) {
if (crxAppIdMap.find(instanceName.toLower()) != crxAppIdMap.end()) {
QString appId = crxAppIdMap[instanceName.toLower()];
qInfo() << "identifyWindowByCrxId: appId " << appId;
ret = new AppInfo(appId);
innerId = ret->getInnerId();
}
}
return ret;
}
AppInfo *WindowIdentify::identifyWindowByRule(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
static WindowPatterns patterns;
qInfo() << "identifyWindowByRule: windowId=" << winInfo->getXid();
AppInfo *ret = nullptr;
QString matchStr = patterns.match(winInfo);
if (matchStr.isEmpty())
return ret;
if (matchStr.size() > 4 && matchStr.startsWith("id=")) {
matchStr.remove(0, 3);
AppInfo* tmp = new AppInfo(matchStr);
// 匹配到了,但是“无效规则“,匹配到程序未安装(优先匹配商店,但是实际程序是原生软件)
if (tmp->isValidApp()) ret = tmp;
else delete tmp;
} else if (matchStr == "env") {
auto process = winInfo->getProcess();
if (process) {
QString launchedDesktopFile = process->getEnv("GIO_LAUNCHED_DESKTOP_FILE");
if (!launchedDesktopFile.isEmpty())
ret = new AppInfo(launchedDesktopFile);
}
} else {
qInfo() << "patterns match bad result";
}
if (ret)
innerId = ret->getInnerId();
return ret;
}
AppInfo *WindowIdentify::identifyWindowByBamf(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
if (_taskmanager->isWaylandEnv()) {
return nullptr;
}
AppInfo *ret = nullptr;
XWindow xid = winInfo->getXid();
qInfo() << "identifyWindowByBamf: windowId=" << xid;
QString desktopFile;
// 重试 bamf 识别,部分的窗口经常要多次调用才能识别到。
for (int i = 0; i < 3; i++) {
desktopFile = _taskmanager->getDesktopFromWindowByBamf(xid);
if (!desktopFile.isEmpty())
break;
}
if (!desktopFile.isEmpty()) {
ret = new AppInfo(desktopFile);
innerId = ret->getInnerId();
}
return ret;
}
AppInfo *WindowIdentify::identifyWindowByPid(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
AppInfo *ret = nullptr;
if (winInfo->getPid() > 10) {
auto entry = _taskmanager->getEntryByWindowId(winInfo->getPid());
if (entry) {
ret = entry->getAppInfo();
innerId = ret->getInnerId();
}
}
return ret;
}
AppInfo *WindowIdentify::identifyWindowByScratch(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
AppInfo *ret = nullptr;
QString desktopFile = scratchDir + winInfo->getInnerId() + ".desktop";
qInfo() << "identifyWindowByScratch: xid " << winInfo->getXid() << " desktopFile" << desktopFile;
QFile file(desktopFile);
if (file.exists()) {
ret = new AppInfo(desktopFile);
innerId = ret->getInnerId();
}
return ret;
}
AppInfo *WindowIdentify::identifyWindowByGtkAppId(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
AppInfo *ret = nullptr;
QString gtkAppId = winInfo->getGtkAppId();
if (!gtkAppId.isEmpty()) {
ret = new AppInfo(gtkAppId);
innerId = ret->getInnerId();
}
qInfo() << "identifyWindowByGtkAppId: gtkAppId:" << gtkAppId;
return ret;
}
AppInfo *WindowIdentify::identifyWindowByWmClass(TaskManager *_taskmanager, WindowInfoX *winInfo, QString &innerId)
{
WMClass wmClass = winInfo->getWMClass();
if (wmClass.instanceName.size() > 0) {
// example:
// WM_CLASS(STRING) = "Brackets", "Brackets"
// wm class instance is Brackets
// try app id org.deepin.flatdeb.brackets
//ret = new AppInfo("org.deepin.flatdeb." + QString(wmClass.instanceName.c_str()).toLower());
if (DesktopInfo("org.deepin.flatdeb." + QString(wmClass.instanceName.c_str()).toLower()).isValidDesktop()) {
AppInfo *appInfo = new AppInfo("org.deepin.flatdeb." + QString(wmClass.instanceName.c_str()).toLower());
innerId = appInfo->getInnerId();
return appInfo;
}
if (DesktopInfo(QString::fromStdString(wmClass.instanceName)).isValidDesktop()) {
AppInfo *appInfo = new AppInfo(wmClass.instanceName.c_str());
innerId = appInfo->getInnerId();
return appInfo;
}
}
if (wmClass.className.size() > 0) {
QString filename = QString::fromStdString(wmClass.className);
bool isValid = DesktopInfo(filename).isValidDesktop();
if (!isValid) {
filename = BamfDesktop::instance()->fileName(wmClass.instanceName.c_str());
isValid = DesktopInfo(filename).isValidDesktop();
}
if (isValid) {
AppInfo *appInfo = new AppInfo(filename);
innerId = appInfo->getInnerId();
return appInfo;
}
}
return nullptr;
}
AppInfo *WindowIdentify::fixAutostartAppInfo(QString fileName)
{
QFileInfo file(fileName);
QString filePath = file.absolutePath();
bool isAutoStart = false;
for (auto dir : QStandardPaths::standardLocations(QStandardPaths::ConfigLocation)) {
if (dir.contains(filePath)) {
isAutoStart = true;
break;
}
}
return isAutoStart ? new AppInfo(file.completeBaseName()) : nullptr;
}
int32_t WindowIdentify::getAndroidUengineId(XWindow winId)
{
// TODO 获取AndroidUengineId
return 0;
}
QString WindowIdentify::getAndroidUengineName(XWindow winId)
{
// TODO 获取AndroidUengineName
return "";
}

View File

@ -0,0 +1,57 @@
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef WINDOWIDENTIFY_H
#define WINDOWIDENTIFY_H
#include "taskmanager/entry.h"
#include "windowpatterns.h"
#include "windowinfok.h"
#include "windowinfox.h"
#include <QObject>
#include <QVector>
#include <QMap>
class AppInfo;
class TaskManager;
typedef AppInfo *(*IdentifyFunc)(TaskManager *, WindowInfoX*, QString &innerId);
// 应用窗口识别类
class WindowIdentify : public QObject
{
Q_OBJECT
public:
explicit WindowIdentify(TaskManager *_taskmanager, QObject *parent = nullptr);
AppInfo *identifyWindow(WindowInfoBase *winInfo, QString &innerId);
AppInfo *identifyWindowX11(WindowInfoX *winInfo, QString &innerId);
AppInfo *identifyWindowWayland(WindowInfoK *winInfo, QString &innerId);
static AppInfo *identifyWindowAndroid(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByPidEnv(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByCmdlineTurboBooster(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByCmdlineXWalk(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByFlatpakAppID(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByCrxId(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByRule(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByBamf(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByPid(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByScratch(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByGtkAppId(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
static AppInfo *identifyWindowByWmClass(TaskManager *_dock, WindowInfoX *winInfo, QString &innerId);
private:
AppInfo *fixAutostartAppInfo(QString fileName);
static int32_t getAndroidUengineId(XWindow winId);
static QString getAndroidUengineName(XWindow winId);
private:
TaskManager *m_taskmanager;
QList<QPair<QString, IdentifyFunc>> m_identifyWindowFuns;
};
#endif // IDENTIFYWINDOW_H

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