Compare commits

...

121 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
391 changed files with 14696 additions and 14170 deletions

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

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

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

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

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

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

View File

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

View File

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

View File

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

175
debian/changelog vendored
View File

@ -1,3 +1,178 @@
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

81
debian/control vendored
View File

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

@ -64,8 +64,8 @@ DockItemManager::DockItemManager(QObject *parent)
connect(quickController, &QuickSettingController::pluginLoaderFinished, this, &DockItemManager::onPluginLoadFinished, Qt::QueuedConnection);
// 应用信号
connect(m_taskmanager, &TaskManager::entryAdded, this, &DockItemManager::appItemAdded);
connect(m_taskmanager, &TaskManager::entryRemoved, this, static_cast<void (DockItemManager::*)(const QString &)>(&DockItemManager::appItemRemoved), Qt::QueuedConnection);
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);
@ -84,7 +84,7 @@ DockItemManager::DockItemManager(QObject *parent)
}
// 刷新图标
QMetaObject::invokeMethod(this, "refreshItemsIcon", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, &DockItemManager::refreshItemsIcon, Qt::QueuedConnection);
}
DockItemManager *DockItemManager::instance(QObject *parent)

View File

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

View File

@ -20,6 +20,7 @@ RecentAppHelper::RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, QObj
{
m_appWidget->installEventFilter(this);
m_recentWidget->installEventFilter(this);
connect(this, &RecentAppHelper::requestUpdateRecentVisible, this, &RecentAppHelper::updateRecentVisible, Qt::QueuedConnection);
}
void RecentAppHelper::setDisplayMode(Dock::DisplayMode displayMode)
@ -170,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)

View File

@ -36,6 +36,7 @@ Q_SIGNALS:
void requestUpdate();
void recentVisibleChanged(bool); // 最近区域是否可见发生变化的信号
void dockAppVisibleChanged(bool); // 驻留应用区域是否可见发生变化的信号
void requestUpdateRecentVisible();
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
@ -44,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);
@ -56,6 +56,7 @@ private:
private Q_SLOTS:
void onModeChanged(int mode);
void updateRecentVisible();
private:
QWidget *m_appWidget;

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
@ -140,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

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

View File

@ -1,47 +0,0 @@
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -c DBusMenu -p dbusmenu com.deepin.menu.Menu.xml
*
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "dbusmenu.h"
/*
* Implementation of interface class DBusMenu
*/
DBusMenu::DBusMenu(const QString &path, QObject *parent)
: QDBusAbstractInterface(staticServerPath(), path, staticInterfaceName(), QDBusConnection::sessionBus(), parent)
{
}
DBusMenu::~DBusMenu()
{
}

View File

@ -1,102 +0,0 @@
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -c DBusMenu -p dbusmenu com.deepin.menu.Menu.xml
*
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef DBUSMENU_H_1436158836
#define DBUSMENU_H_1436158836
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface com.deepin.menu.Menu
*/
class DBusMenu: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticServerPath()
{ return "com.deepin.menu"; }
static inline const char *staticInterfaceName()
{ return "com.deepin.menu.Menu"; }
public:
DBusMenu(const QString &path,QObject *parent = 0);
~DBusMenu();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> SetItemActivity(const QString &itemId, bool isActive)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(itemId) << QVariant::fromValue(isActive);
return asyncCallWithArgumentList(QStringLiteral("SetItemActivity"), argumentList);
}
inline QDBusPendingReply<> SetItemChecked(const QString &itemId, bool checked)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(itemId) << QVariant::fromValue(checked);
return asyncCallWithArgumentList(QStringLiteral("SetItemChecked"), argumentList);
}
inline QDBusPendingReply<> SetItemText(const QString &itemId, const QString &text)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(itemId) << QVariant::fromValue(text);
return asyncCallWithArgumentList(QStringLiteral("SetItemText"), argumentList);
}
inline QDBusPendingReply<> ShowMenu(const QString &menuJsonContent)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(menuJsonContent);
return asyncCallWithArgumentList(QStringLiteral("ShowMenu"), argumentList);
}
Q_SIGNALS: // SIGNALS
void ItemInvoked(const QString &itemId, bool checked);
void MenuUnregistered();
};
namespace com {
namespace deepin {
namespace menu {
typedef ::DBusMenu Menu;
}
}
}
#endif

View File

@ -1,47 +0,0 @@
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -c DBusMenuManager -p dbusmenumanager com.deepin.menu.Manager.xml
*
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#include "dbusmenumanager.h"
/*
* Implementation of interface class DBusMenuManager
*/
DBusMenuManager::DBusMenuManager(QObject *parent)
: QDBusAbstractInterface(staticServerPath(), staticInterfacePath(), staticInterfaceName(), QDBusConnection::sessionBus(), parent)
{
}
DBusMenuManager::~DBusMenuManager()
{
}

View File

@ -1,87 +0,0 @@
/*
* Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp -c DBusMenuManager -p dbusmenumanager com.deepin.menu.Manager.xml
*
* qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#ifndef DBUSMENUMANAGER_H_1436158928
#define DBUSMENUMANAGER_H_1436158928
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
/*
* Proxy class for interface com.deepin.menu.Manager
*/
class DBusMenuManager: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticServerPath()
{ return "com.deepin.menu"; }
static inline const char *staticInterfacePath()
{ return "/com/deepin/menu"; }
static inline const char *staticInterfaceName()
{ return "com.deepin.menu.Manager"; }
public:
explicit DBusMenuManager(QObject *parent = 0);
~DBusMenuManager();
public Q_SLOTS: // METHODS
inline QDBusPendingReply<QDBusObjectPath> RegisterMenu()
{
QList<QVariant> argumentList;
return asyncCallWithArgumentList(QStringLiteral("RegisterMenu"), argumentList);
}
inline QDBusPendingReply<> UnregisterMenu(const QString &menuObjectPath)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(menuObjectPath);
return asyncCallWithArgumentList(QStringLiteral("UnregisterMenu"), argumentList);
}
Q_SIGNALS: // SIGNALS
};
namespace com {
namespace deepin {
namespace menu {
typedef ::DBusMenuManager Manager;
}
}
}
#endif

View File

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

View File

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

View File

@ -755,7 +755,7 @@ void AppItem::showPreview()
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);

View File

@ -297,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);

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

@ -39,8 +39,6 @@ DUTIL_USE_NAMESPACE
const QString g_cfgPath = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation)[0] + "/dde-cfg.ini";
using namespace std;
/**
* @brief IsSaveMode
* @return
@ -161,6 +159,10 @@ int main(int argc, char *argv[])
DockApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
DockApplication app(argc, argv);
// NOTE: dde-shell load dde-dock plugins and mark loader program DS_APP_ID as dde-dock
// so need reset DGuiApplication pallette to follow system
DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::ColorType::UnknownType);
//崩溃信号
signal(SIGSEGV, sig_crash);
signal(SIGILL, sig_crash);
@ -176,7 +178,7 @@ int main(int argc, char *argv[])
app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
// 设置日志输出到控制台以及文件
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();

View File

@ -10,7 +10,8 @@
#include <QCryptographicHash>
AppInfo::AppInfo(DesktopInfo &info)
: m_isValid(true)
: m_installed(false)
, m_isValid(true)
{
init(info);
}
@ -43,9 +44,10 @@ void AppInfo::init(DesktopInfo &info)
m_fileName = info.getDesktopFilePath();
m_id = info.getId();
m_icon = info.getIcon();
for (const auto & action : info.getActions()) {
m_actions.push_back(action);
}
m_installed = info.isInstalled();
auto actions = info.getActions();
std::copy(actions.begin(), actions.end(), std::back_inserter(m_actions));
}
QString AppInfo::genInnerIdWithDesktopInfo(DesktopInfo &info)

View File

@ -30,6 +30,10 @@ 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:";

View File

@ -3,11 +3,16 @@
// 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)
@ -15,13 +20,36 @@ DBusHandler::DBusHandler(TaskManager *taskmanager, QObject *parent)
, 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()
@ -54,16 +82,50 @@ QString DBusHandler::getCurrentWM()
void DBusHandler::launchApp(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);
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");
@ -209,3 +271,73 @@ QString DBusHandler::getDesktopFromWindowByBamf(XWindow windowId)
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

@ -6,6 +6,7 @@
#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"
@ -39,6 +40,10 @@ public:
/************************* 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);
@ -58,10 +63,19 @@ public:
// 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;
@ -70,6 +84,9 @@ private:
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

@ -4,6 +4,7 @@
#include "desktopinfo.h"
#include "locale.h"
#include "taskmanager/common.h"
#include "unistd.h"
#include <QDebug>
@ -13,13 +14,14 @@
#include <QSettings>
#include <QStandardPaths>
#include <QVector>
#include <qlocale.h>
#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);
@ -28,14 +30,17 @@ DesktopInfo::DesktopInfo(const QString &desktopfile)
desktopFileInfo.setFile(desktopfilepath);
}
if (!desktopFileInfo.isAbsolute()) {
for (auto dir: QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation)) {
QString path = dir.append("/").append(desktopfilepath);
if (QFile::exists(path)) desktopFileInfo.setFile(path);
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.absoluteFilePath();
m_desktopFilePath = desktopFileInfo.canonicalFilePath();
m_isValid = desktopFileInfo.isAbsolute() && QFile::exists(desktopFileInfo.absoluteFilePath());
m_desktopFile.reset(new QSettings(m_desktopFilePath, QSettings::IniFormat));
m_desktopFile->setIniCodec("utf-8");
@ -73,6 +78,11 @@ bool DesktopInfo::isValidDesktop()
return m_isValid;
}
bool DesktopInfo::isInstalled()
{
return m_isInstalled;
}
/** if return true, item is shown
* @brief DesktopInfo::shouldShow
* @return
@ -150,8 +160,7 @@ QList<DesktopAction> DesktopInfo::getActions()
{
QList<DesktopAction> actions;
for (const auto &mainKey : m_desktopFile->childGroups()) {
if (mainKey.startsWith("Desktop Action")
|| mainKey.endsWith("Shortcut Group")) {
if (mainKey.startsWith(DesktopFileActionKey)) {
DesktopAction action;
action.name = getLocaleStr(mainKey, KeyName);
action.exec = m_desktopFile->value(mainKey + '/' + KeyExec).toString();

View File

@ -95,6 +95,7 @@ private:
static QStringList currentDesktops;
bool m_isValid;
bool m_isInstalled;
QString m_id;
QString m_name;

View File

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

View File

@ -127,7 +127,7 @@ AppInfo *Entry::getAppInfo()
void Entry::setAppInfo(AppInfo *appinfo)
{
if (m_appInfo.data() == appinfo) {
if (m_appInfo.data() == appinfo || appinfo == nullptr) {
return;
}

View File

@ -11,23 +11,30 @@
#include "taskmanager.h"
#include "windowinfok.h"
#include "dbushandler.h"
#include "docksettings.h"
#include "windowinfomap.h"
#include "windowidentify.h"
#include "waylandmanager.h"
#include "windowinfobase.h"
#include "dbusutil.h"
#include "org_deepin_dde_kwayland_plasmawindow.h"
#include <QDir>
#include <QMap>
#include <QTimer>
#include <QList>
#include <QPixmap>
#include <cstdint>
#include <dtkcore_global.h>
#include <functional>
#include <iterator>
#include <memory>
#include <algorithm>
#include <qpixmap.h>
#include <dutil.h>
DCORE_USE_NAMESPACE
#define SETTING DockSettings::instance()
#define XCB XCBUtils::instance()
@ -46,6 +53,9 @@ TaskManager::TaskManager(QObject *parent)
: m_showRecent(DockSettings::instance()->showRecent())
, m_entriesSum(0)
, m_hideState(HideState::Unknown)
, m_ddeLauncherVisible(false)
, m_trayGridWidgetVisible(false)
, m_popupVisible(false)
, m_entries(new Entries(this))
, m_windowIdentify(new WindowIdentify(this))
, m_dbusHandler(new DBusHandler(this))
@ -86,6 +96,20 @@ TaskManager::TaskManager(QObject *parent)
connect(m_x11Manager, &X11Manager::requestHandleActiveWindowChange, this, &TaskManager::handleActiveWindowChanged);
connect(m_x11Manager, &X11Manager::requestAttachOrDetachWindow, this, &TaskManager::attachOrDetachWindow);
}
connect(m_dbusHandler, &DBusHandler::appUninstalled, this, [this] (const QDBusObjectPath &objectPath, const QStringList &interfaces) {
Q_UNUSED(interfaces)
QString desktopFile = DUtil::unescapeFromObjectPath(objectPath.path());
QString desktopName = desktopFile.split('/').last();
QList<Entry *> entries = m_entries->getEntries();
auto desktopEntryIter = std::find_if(entries.begin(), entries.end(), [desktopName] (Entry *entry) {
return entry->getDesktopFile().contains(desktopName);
});
if (desktopEntryIter != entries.end()) {
undockEntry(*desktopEntryIter);
} else {
qWarning() << "The entry which is to be removed is not found!";
}
});
}
TaskManager::~TaskManager()
@ -115,57 +139,13 @@ bool TaskManager::dockEntry(Entry *entry, bool moveToEnd)
return false;
}
if (appInfo->getFileName().contains(scratchDir)) {
qInfo() << "needScratchDesktop: no, desktop in scratchDir";
return false;
}
return true;
};
if (needScratchDesktop()) {
// 创建scratch Desktop file
QDir dir;
if (!dir.mkpath(scratchDir)) {
qWarning() << "create scratch Desktopfile failed";
return false;
}
QFile file;
QString newDesktopFile;
if (appInfo) {
QString newFile = scratchDir + appInfo->getInnerId() + ".desktop";
// 在目标文件存在的情况下,先删除,防止出现驻留不成功的情况
if (QFile::exists(newFile)) QFile::remove(newFile);
if (file.copy(appInfo->getFileName(), newFile))
newDesktopFile = newFile;
} else {
WindowInfoBase *current = entry->getCurrentWindowInfo();
if (current) {
QString appId = current->getInnerId();
QString title = current->getDisplayName();
QString icon = current->getIcon();
if (icon.isEmpty()) icon = "application-default-icon";
QString cmd = entry->getCmdLine() + "%U";
QString fileNmae = scratchDir + appId + ".desktop";
QString desktopContent = QString(dockedItemTemplate).arg(title).arg(cmd).arg(icon);
file.setFileName(fileNmae);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
file.write(desktopContent.toStdString().c_str(), desktopContent.size());
file.close();
newDesktopFile = fileNmae;
}
}
}
if (newDesktopFile.isEmpty())
return false;
appInfo = new AppInfo(newDesktopFile);
entry->setAppInfo(appInfo);
entry->updateIcon();
entry->setInnerId(appInfo->getInnerId());
m_dbusHandler->sendFailedDockNotification(entry->getName());
return false;
}
// 如果是最近打开应用通过右键菜单的方式驻留且当前是时尚模式那么就让entry驻留到末尾
@ -282,6 +262,29 @@ bool TaskManager::shouldShowOnDock(WindowInfoBase *info)
return false;
}
/**
* @brief TaskManager::setDdeLauncherVisible
* @param visible
*/
void TaskManager::setDdeLauncherVisible(bool visible)
{
m_ddeLauncherVisible = visible;
}
/**
* @brief TaskManager::setTrayGridWidgetVisible
* @param visible
*/
void TaskManager::setTrayGridWidgetVisible(bool visible)
{
m_trayGridWidgetVisible = visible;
}
void TaskManager::setPopupVisible(bool visible)
{
m_popupVisible = visible;
}
/**
* @brief TaskManager::getWMName
* @return
@ -387,7 +390,7 @@ void TaskManager::doActiveWindow(XWindow xid)
}
XCB->changeActiveWindow(xid);
QTimer::singleShot(50, [&] {
QTimer::singleShot(50, [xid] {
XCB->restackWindow(xid);
});
}
@ -499,6 +502,11 @@ bool TaskManager::requestDock(QString desktopFile, int index)
return false;
}
if (m_dbusHandler->newStartManagerAvaliable() && !app->isInstalled()) {
m_dbusHandler->sendFailedDockNotification(app->getName());
return false;
}
Entry *entry = m_entries->getByInnerId(app->getInnerId());
if (!entry)
entry = new Entry(this, app, app->getInnerId());
@ -638,12 +646,6 @@ void TaskManager::initSettings()
connect(SETTING, &DockSettings::hideModeChanged, this, [ this ](HideMode mode) {
this->updateHideState(false);
});
connect(SETTING, &DockSettings::displayModeChanged, this, [](DisplayMode mode) {
qInfo() << "display mode change to " << static_cast<int>(mode);
});
connect(SETTING, &DockSettings::positionModeChanged, this, [](Position mode) {
qInfo() << "position mode change to " << static_cast<int>(mode);
});
connect(SETTING, &DockSettings::forceQuitAppChanged, this, [ this ](ForceQuitAppMode mode) {
qInfo() << "forceQuitApp change to " << int(mode);
m_forceQuitAppStatus = mode;
@ -651,6 +653,10 @@ void TaskManager::initSettings()
});
connect(SETTING, &DockSettings::showRecentChanged, this, &TaskManager::onShowRecentChanged);
connect(SETTING, &DockSettings::showMultiWindowChanged, this, &TaskManager::onShowMultiWindowChanged);
connect(SETTING, &DockSettings::displayModeChanged, this, &TaskManager::setDisplayMode);
connect(SETTING, &DockSettings::displayModeChanged, this, [this]() {
Q_EMIT windowMarginChanged(windowMargin());
});
}
/**
@ -675,6 +681,10 @@ void TaskManager::loadAppInfos()
if (!info.isValidDesktop())
continue;
// 新AM接口导致用户自定义的desktopfile不再加载
if (m_dbusHandler->newStartManagerAvaliable() && !info.isInstalled())
continue;
AppInfo *appInfo = new AppInfo(info);
Entry *entryObj = new Entry(this, appInfo, appInfo->getInnerId());
entryObj->setIsDocked(isDocked);
@ -867,7 +877,7 @@ Entry *TaskManager::getDockedEntryByDesktopFile(const QString &desktopFile)
*/
bool TaskManager::shouldHideOnSmartHideMode()
{
if (!m_activeWindow)
if (!m_activeWindow || m_ddeLauncherVisible || m_trayGridWidgetVisible || m_popupVisible)
return false;
if (!m_isWayland) {
@ -967,6 +977,11 @@ QVector<XWindow> TaskManager::getActiveWinGroup(XWindow xid)
*/
void TaskManager::updateHideState(bool delay)
{
if (preventDockAutoHide()) {
setPropHideState(HideState::Show);
return;
}
HideMode mode = SETTING->getHideMode();
switch (mode) {
case HideMode::KeepShowing:
@ -996,7 +1011,7 @@ void TaskManager::setPropHideState(HideState state)
if (state != m_hideState) {
qDebug() << "current hide state: " << m_hideState;
m_hideState = state;
Q_EMIT hideStateChanged(static_cast<int>(m_hideState));
Q_EMIT hideStateChanged(m_hideState);
}
}
@ -1151,7 +1166,7 @@ void TaskManager::handleActiveWindowChanged(WindowInfoBase *info)
m_activeWindow = info;
XWindow winId = m_activeWindow->getXid();
m_entries->handleActiveWindowChanged(winId);
updateHideState(true);
QTimer::singleShot(200, std::bind(&TaskManager::updateHideState, this, true));
}
/**
@ -1402,7 +1417,7 @@ void TaskManager::setDisplayMode(int mode)
{
DisplayMode displayMode = static_cast<DisplayMode>(mode);
SETTING->setDisplayMode(displayMode);
// m_entries->setDisplayMode(displayMode);
m_entries->setDisplayMode(displayMode);
}
/**
@ -1518,6 +1533,11 @@ void TaskManager::setPosition(int position)
SETTING->setPositionMode(Position(position));
}
uint TaskManager::windowMargin() const
{
return SETTING->getDisplayMode() == Dock::Efficient ? 0 : 10;
}
/**
* @brief TaskManager::getShowTimeout
* @return
@ -1585,4 +1605,9 @@ void TaskManager::cancelPreviewWindow()
bool TaskManager::showMultiWindow() const
{
return m_showMultiWindow;
}
}
bool TaskManager::preventDockAutoHide() const
{
return m_ddeLauncherVisible || m_popupVisible || m_trayGridWidgetVisible;
}

View File

@ -40,6 +40,8 @@ public:
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);
@ -85,6 +87,7 @@ public:
void setIconSize(uint size);
int getPosition();
void setPosition(int position);
uint windowMargin() const;
uint getShowTimeout();
void setShowTimeout(uint timeout);
uint getWindowSizeEfficient();
@ -126,6 +129,7 @@ public:
void previewWindow(uint xid);
void cancelPreviewWindow();
bool preventDockAutoHide() const;
Q_SIGNALS:
void serviceRestarted();
@ -135,6 +139,7 @@ Q_SIGNALS:
void frontendWindowRectChanged(const QRect &dockRect);
void showRecentChanged(bool);
void showMultiWindowChanged(bool);
void windowMarginChanged(uint);
public Q_SLOTS:
void updateHideState(bool delay);
@ -174,6 +179,9 @@ private:
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窗口管理

View File

@ -13,7 +13,7 @@
#include <QDebug>
#include <QThread>
#include <qstandardpaths.h>
#include <QDBusConnection>
#define XCB XCBUtils::instance()
@ -74,11 +74,28 @@ WindowIdentify::WindowIdentify(TaskManager *_taskmanager, QObject *parent)
m_identifyWindowFuns << qMakePair(QString("FlatpakAppID"), &identifyWindowByFlatpakAppID);
m_identifyWindowFuns << qMakePair(QString("CrxId"), &identifyWindowByCrxId);
m_identifyWindowFuns << qMakePair(QString("Rule"), &identifyWindowByRule);
m_identifyWindowFuns << qMakePair(QString("Bamf"), &identifyWindowByBamf);
m_identifyWindowFuns << qMakePair(QString("Pid"), &identifyWindowByPid);
m_identifyWindowFuns << qMakePair(QString("Scratch"), &identifyWindowByScratch);
m_identifyWindowFuns << qMakePair(QString("GtkAppId"), &identifyWindowByGtkAppId);
m_identifyWindowFuns << qMakePair(QString("WmClass"), &identifyWindowByWmClass);
// should remove bamf identify and turn to new AM
auto *dbusWatcher = new QDBusServiceWatcher(QStringLiteral("org.ayatana.bamf"), QDBusConnection::sessionBus(),
QDBusServiceWatcher::WatchForOwnerChange, this);
auto ifc = QDBusConnection::sessionBus().interface();
if (ifc->isServiceRegistered(QStringLiteral("org.ayatana.bamf"))) {
m_identifyWindowFuns << qMakePair(QString("Bamf"), &identifyWindowByBamf);
}
connect(dbusWatcher, &QDBusServiceWatcher::serviceRegistered, this, [this](){
m_identifyWindowFuns << qMakePair(QString("Bamf"), &identifyWindowByBamf);
});
connect(dbusWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this](){
m_identifyWindowFuns.removeAll(qMakePair(QString("Bamf"), &identifyWindowByBamf));
});
}
AppInfo *WindowIdentify::identifyWindow(WindowInfoBase *winInfo, QString &innerId)
@ -379,7 +396,10 @@ AppInfo *WindowIdentify::identifyWindowByRule(TaskManager *_taskmanager, WindowI
if (matchStr.size() > 4 && matchStr.startsWith("id=")) {
matchStr.remove(0, 3);
ret = new AppInfo(matchStr);
AppInfo* tmp = new AppInfo(matchStr);
// 匹配到了,但是“无效规则“,匹配到程序未安装(优先匹配商店,但是实际程序是原生软件)
if (tmp->isValidApp()) ret = tmp;
else delete tmp;
} else if (matchStr == "env") {
auto process = winInfo->getProcess();
if (process) {

View File

@ -121,7 +121,7 @@ void X11Manager::listenXEventUseXlib()
break;
}
default:
qDebug() << "unused event type " << event.type;
//qDebug() << "unused event type " << event.type;
break;
}
}

View File

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

View File

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

View File

@ -46,9 +46,9 @@ void DockSettings::init()
} else if ( key == keyQuickPlugins) {
Q_EMIT quickPluginsChanged(m_dockSettings->value(keyQuickPlugins).toStringList());
} else if ( key == keyWindowSizeFashion) {
Q_EMIT windowSizeFashionChanged(m_dockSettings->value(keyWindowSizeFashion).toUInt());
Q_EMIT windowSizeFashionChanged(m_dockSettings->value(keyWindowSizeFashion, 48).toUInt());
} else if ( key == keyWindowSizeEfficient) {
Q_EMIT windowSizeEfficientChanged(m_dockSettings->value(keyWindowSizeEfficient).toUInt());
Q_EMIT windowSizeEfficientChanged(m_dockSettings->value(keyWindowSizeEfficient, 40).toUInt());
}
});
}
@ -176,7 +176,7 @@ uint DockSettings::getWindowSizeEfficient()
{
uint size = 40;
if (m_dockSettings) {
size = m_dockSettings->value(keyWindowSizeEfficient).toUInt();
size = m_dockSettings->value(keyWindowSizeEfficient, size).toUInt();
}
return size;
}
@ -192,7 +192,7 @@ uint DockSettings::getWindowSizeFashion()
{
uint size = 48;
if (m_dockSettings) {
size = m_dockSettings->value(keyWindowSizeFashion).toUInt();
size = m_dockSettings->value(keyWindowSizeFashion, size).toUInt();
}
return size;
}
@ -398,6 +398,7 @@ void DockSettings::setQuickPlugin(QString plugin)
if (!m_dockSettings)
return;
QStringList plugins = m_dockSettings->value(keyQuickPlugins).toStringList();
if (plugins.contains(plugin)) return;
m_dockSettings->setValue(keyQuickPlugins, plugins << plugin);
}
@ -429,6 +430,7 @@ void DockSettings::setTrayItemOnDock(QString item)
if (!m_dockSettings)
return;
QStringList items = m_dockSettings->value(keyQuickTrayName).toStringList();
if (items.contains(item)) return;
m_dockSettings->setValue(keyQuickTrayName, items << item);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -6,8 +6,6 @@
#pragma once
#include <memory>
using namespace std;
template <class T>
class Singleton
{

View File

@ -1,4 +1,4 @@
// Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
// Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
@ -12,6 +12,7 @@
#include <DFontSizeManager>
#include <DDBusSender>
#include <DGuiApplicationHelper>
#include <DConfig>
#include <QHBoxLayout>
#include <QPainter>
@ -19,6 +20,7 @@
#include <QMenu>
#include <QPainterPath>
#include <QMouseEvent>
#include <QFontMetrics>
DWIDGET_USE_NAMESPACE
DGUI_USE_NAMESPACE
@ -30,18 +32,25 @@ static QMap<int, QString> dateFormat{{ 0,"yyyy/M/d" }, { 1,"yyyy-M-d" }, { 2,"yy
{ 4,"yyyy-MM-dd" }, { 5,"yyyy.MM.dd" }, { 6,"yy/M/d" }, { 7,"yy-M-d" }, { 8,"yy.M.d" }};
static QMap<int, QString> timeFormat{{0, "h:mm"}, {1, "hh:mm"}};
const QString localeName_key = "localeName";
const QString shortDateFormat_key = "shortDateFormat";
const QString shortTimeFormat_key = "shortTimeFormat";
const QString longDateFormat_key = "longDateFormat";
const QString longTimeFormat_key = "longTimeFormat";
DateTimeDisplayer::DateTimeDisplayer(bool showMultiRow, QWidget *parent)
: QWidget (parent)
, m_timedateInter(new Timedate("org.deepin.dde.Timedate1", "/org/deepin/dde/Timedate1", QDBusConnection::sessionBus(), this))
, m_position(Dock::Position::Bottom)
, m_dateFont(DFontSizeManager::instance()->t10())
, m_timeFont(timeFont())
, m_dateFont(QFont())
, m_timeFont(QFont())
, m_tipsWidget(new Dock::TipsWidget(this))
, m_menu(new QMenu(this))
, m_tipsTimer(new QTimer(this))
, m_currentSize(0)
, m_oneRow(false)
, m_showMultiRow(showMultiRow)
, m_config(DTK_CORE_NAMESPACE::DConfig::createGeneric("org.deepin.region-format", QString(), this))
{
m_tipPopupWindow.reset(new DockPopupWindow);
// 日期格式变化的时候,需要重绘
@ -62,6 +71,62 @@ DateTimeDisplayer::DateTimeDisplayer(bool showMultiRow, QWidget *parent)
if (Utils::IS_WAYLAND_DISPLAY)
m_tipPopupWindow->setWindowFlags(m_tipPopupWindow->windowFlags() | Qt::FramelessWindowHint);
m_tipPopupWindow->hide();
m_locale = QLocale::system();
initDConfig();
}
void DateTimeDisplayer::initDConfig()
{
QLocale currentLocale = QLocale::system();
if (!m_config->isValid())
return;
if (!m_config->isDefaultValue(localeName_key)) {
m_locale = QLocale(m_config->value(localeName_key).toString());
} else {
m_locale = currentLocale;
}
if (!m_config->isDefaultValue(shortDateFormat_key)) {
m_shortDateFormatStr = m_config->value(shortDateFormat_key).toString();
} else {
m_shortDateFormatStr = currentLocale.dateFormat(QLocale::ShortFormat);
}
if (!m_config->isDefaultValue(shortDateFormat_key)) {
m_longDateFormatStr = m_config->value(longDateFormat_key).toString();
} else {
m_longDateFormatStr = currentLocale.dateFormat(QLocale::LongFormat);
}
if (!m_config->isDefaultValue(shortTimeFormat_key)) {
m_shortTimeFormatStr = m_config->value(shortTimeFormat_key).toString();
} else {
m_shortTimeFormatStr = currentLocale.timeFormat(QLocale::ShortFormat);
}
if (!m_config->isDefaultValue(longTimeFormat_key)) {
m_longTimeFormatStr = m_config->value(longTimeFormat_key).toString();
} else {
m_longTimeFormatStr = currentLocale.timeFormat(QLocale::LongFormat);
}
connect(m_config, &DTK_CORE_NAMESPACE::DConfig::valueChanged, this, [this] (const QString &key) {
if (key == shortDateFormat_key) {
m_shortDateFormatStr = m_config->value(key).toString();
} else if (key == shortTimeFormat_key) {
m_shortTimeFormatStr = m_config->value(key).toString();
} else if (key == localeName_key) {
m_locale = QLocale(m_config->value(key).toString());
} else if (key == longDateFormat_key) {
m_longDateFormatStr = m_config->value(key).toString();
} else if (key == longTimeFormat_key) {
m_longTimeFormatStr = m_config->value(key).toString();
}
update();
});
}
DateTimeDisplayer::~DateTimeDisplayer()
@ -133,10 +198,10 @@ void DateTimeDisplayer::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event);
DDBusSender().service("org.deepin.dde.Widgets1")
.path("/org/deepin/dde/Widgets1")
.interface("org.deepin.dde.Widgets1")
.method("Toggle").call();
DDBusSender().service("com.deepin.Calendar")
.path("/com/deepin/Calendar")
.interface("com.deepin.Calendar")
.method("RaiseWindow").call();
}
QString DateTimeDisplayer::getTimeString(const Dock::Position &position) const
@ -144,15 +209,10 @@ QString DateTimeDisplayer::getTimeString(const Dock::Position &position) const
QString tFormat = QString("hh:mm");
if (timeFormat.contains(m_shortDateFormat))
tFormat = timeFormat[m_shortDateFormat];
if (!m_shortTimeFormatStr.isEmpty())
tFormat = m_shortTimeFormatStr;
if (!m_use24HourFormat) {
if (position == Dock::Top || position == Dock::Bottom)
tFormat = tFormat.append(" AP");
else
tFormat = tFormat.append("\nAP");
}
return QDateTime::currentDateTime().toString(tFormat);
return m_locale.toString(QDateTime::currentDateTime(), tFormat);
}
QString DateTimeDisplayer::getDateString() const
@ -165,9 +225,12 @@ QString DateTimeDisplayer::getDateString(const Dock::Position &position) const
QString shortDateFormat = "yyyy-MM-dd";
if (dateFormat.contains(m_shortDateFormat))
shortDateFormat = dateFormat.value(m_shortDateFormat);
if (!m_shortDateFormatStr.isEmpty())
shortDateFormat = m_shortDateFormatStr;
// 如果是左右方向,则不显示年份
if (position == Dock::Position::Left || position == Dock::Position::Right) {
static QStringList yearStrList{"yyyy/", "yyyy-", "yyyy.", "yy/", "yy-", "yy."};
static QStringList yearStrList{"yyyy/", "/yyyy", "yyyy-", "-yyyy", "yyyy.", ".yyyy",
"yy/", "/yy", "yy-", "-yy", "yy.", ".yy"};
for (int i = 0; i < yearStrList.size() ; i++) {
const QString &yearStr = yearStrList[i];
if (shortDateFormat.contains(yearStr)) {
@ -177,7 +240,7 @@ QString DateTimeDisplayer::getDateString(const Dock::Position &position) const
}
}
return QDateTime::currentDateTime().toString(shortDateFormat);
return m_locale.toString(QDateTime::currentDateTime(), shortDateFormat);
}
DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo(const Dock::Position &position) const
@ -189,16 +252,15 @@ DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo(const Dock::Posi
info.m_time = getTimeString(position);
info.m_date = getDateString(position);
if (m_showMultiRow && m_dateFont.pixelSize() + m_timeFont.pixelSize() > height() - 8) {
m_dateFont.setPixelSize(height() / 2 - 5);
m_timeFont.setPixelSize(height() / 2 - 3);
}
// 如果是左右方向
if (position == Dock::Position::Left || position == Dock::Position::Right) {
int textWidth = rect().width();
info.m_timeRect = QRect(0, 0, textWidth, DATETIMESIZE / 2);
info.m_dateRect = QRect(0, DATETIMESIZE / 2 + 1, textWidth, DATETIMESIZE / 2);
int timeHeight = QFontMetrics(m_timeFont).boundingRect(info.m_time).height() * (info.m_time.count('\n') + 1);
int dateHeight = QFontMetrics(m_dateFont).boundingRect(info.m_date).height();
info.m_timeRect = QRect(0, 0, textWidth, timeHeight);
info.m_dateRect = QRect(0, timeHeight, textWidth, dateHeight);
return info;
}
int timeWidth = QFontMetrics(m_timeFont).boundingRect(info.m_time).width() + 2;
@ -233,12 +295,7 @@ DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo(const Dock::Posi
void DateTimeDisplayer::onTimeChanged()
{
const QDateTime currentDateTime = QDateTime::currentDateTime();
if (m_use24HourFormat)
m_tipsWidget->setText(QLocale().toString(currentDateTime.date()) + currentDateTime.toString(" HH:mm:ss"));
else
m_tipsWidget->setText(QLocale().toString(currentDateTime.date()) + currentDateTime.toString(" hh:mm:ss AP"));
m_tipsWidget->setText(m_locale.toString(QDate::currentDate(), m_longDateFormatStr) + QString(" ") + m_locale.toString(QTime::currentTime(), m_longTimeFormatStr));
// 如果时间和日期有一个不等,则实时刷新界面
if (m_lastDateString != getDateString() || m_lastTimeString != getTimeString())
@ -247,14 +304,9 @@ void DateTimeDisplayer::onTimeChanged()
void DateTimeDisplayer::onDateTimeFormatChanged()
{
int lastSize = m_currentSize;
m_shortDateFormat = m_timedateInter->shortDateFormat();
m_use24HourFormat = m_timedateInter->use24HourFormat();
// 此处需要强制重绘因为在重绘过程中才会改变m_currentSize信息方便在后面判断是否需要调整尺寸
repaint();
// 如果日期时间的格式发生了变化,需要通知外部来调整日期时间的尺寸
if (lastSize != m_currentSize)
Q_EMIT requestUpdate();
}
void DateTimeDisplayer::paintEvent(QPaintEvent *e)
@ -265,7 +317,6 @@ void DateTimeDisplayer::paintEvent(QPaintEvent *e)
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(palette().brightText(), 1));
int timeAlignFlag = Qt::AlignCenter;
int dateAlignFlag = Qt::AlignCenter;
@ -273,16 +324,14 @@ void DateTimeDisplayer::paintEvent(QPaintEvent *e)
if (m_showMultiRow) {
timeAlignFlag = Qt::AlignHCenter | Qt::AlignBottom;
dateAlignFlag = Qt::AlignHCenter | Qt::AlignTop;
} else {
if (m_timeFont.pixelSize() >= rect().height()) {
m_timeFont.setPixelSize(rect().height() - 2);
m_dateFont.setPixelSize(rect().height() - 2);
}
}
painter.setFont(m_timeFont);
painter.setPen(QPen(palette().brightText(), 2));
painter.drawText(textRect(info.m_timeRect), timeAlignFlag, info.m_time);
painter.setFont(m_dateFont);
painter.setPen(QPen(palette().brightText(), 1));
painter.drawText(textRect(info.m_dateRect), dateAlignFlag, info.m_date);
updateLastData(info);
@ -316,41 +365,40 @@ QPoint DateTimeDisplayer::tipsPoint() const
return window()->mapToGlobal(pointInTopWidget);
}
QFont DateTimeDisplayer::timeFont() const
void DateTimeDisplayer::updateFont() const
{
if (m_position == Dock::Position::Left || m_position == Dock::Position::Right)
return DFontSizeManager::instance()->t6();
static constexpr int MINHEIGHT = 40;
// 如果是上下方向,且当前只有一行,则始终显示小号字体
if (m_oneRow && ( Dock::Position::Top == m_position || Dock::Position::Bottom == m_position )) {
return DFontSizeManager::instance()->t10();
auto info = getTimeString(m_position);
// "xx:xx\nAP" 获取到前 xx:xx 部分
info = info.left(info.indexOf('\n'));
if (m_position == Dock::Position::Left || m_position == Dock::Position::Right) {
auto f = QFont();
bool caled = false;
f.setPixelSize(100);
// 左右时根据获取可以全部显示文本的最小的宽度, 且最大只到40
while(width() > 0 && f.pixelSize() > 2 &&
(QFontMetrics(f).boundingRect(info).width() > qMin(DATETIMESIZE, width()) - 4)) {
f.setPixelSize(f.pixelSize() - 1);
caled = true;
}
// 经过正确的计算后才能更新字体大小
if (caled) {
m_timeFont.setPixelSize(f.pixelSize());
m_dateFont.setPixelSize(f.pixelSize() - 2);
}
return;
}
QList<QFont> dateFontSize = { DFontSizeManager::instance()->t8(),
DFontSizeManager::instance()->t7(),
DFontSizeManager::instance()->t6(),
DFontSizeManager::instance()->t5() };
// dock size >= 70 get max font(t5) size
int index = qMin(qMax(((rect().height() - MINHEIGHT) / 10), 0), dateFontSize.size() - 1);
return dateFontSize[index];
if ((Dock::Position::Top == m_position || Dock::Position::Bottom == m_position )) {
// 单行时保持高度的一半双行时尽量和高度一致但最大只到12。
auto s = height() / (m_oneRow ? 2 : 1) - 2;
m_timeFont.setPixelSize(std::min(s, 12));
// 双行时日期比时间字体小两个像素。
m_dateFont.setPixelSize(std::min(s, 12) - (m_oneRow ? 0 : 2));
}
}
void DateTimeDisplayer::createMenuItem()
{
QAction *timeFormatAction = new QAction(this);
timeFormatAction->setText(m_use24HourFormat ? tr("12-hour time"): tr("24-hour time"));
connect(timeFormatAction, &QAction::triggered, this, [ = ] {
bool use24hourformat = !m_use24HourFormat;
// 此时调用 dbus 更新时间格式但是本地 m_use24HourFormat 未更新,所以需要使用新变量,设置新格式
m_timedateInter->setUse24HourFormat(use24hourformat);
timeFormatAction->setText(use24hourformat ? tr("12-hour time") : tr("24-hour time"));
});
m_menu->addAction(timeFormatAction);
if (!QFile::exists(ICBC_CONF_FILE)) {
QAction *timeSettingAction = new QAction(tr("Time settings"), this);
connect(timeSettingAction, &QAction::triggered, this, [ = ] {
@ -396,8 +444,14 @@ void DateTimeDisplayer::leaveEvent(QEvent *event)
m_tipPopupWindow->hide();
}
QString DateTimeDisplayer::getTimeString() const
{
return getTimeString(m_position);
}
void DateTimeDisplayer::updateLastData(const DateTimeInfo &info)
{
int lastSize = m_currentSize;
m_lastDateString = info.m_date;
m_lastTimeString = info.m_time;
QSize dateTimeSize = suitableSize();
@ -405,22 +459,15 @@ void DateTimeDisplayer::updateLastData(const DateTimeInfo &info)
m_currentSize = dateTimeSize.width();
else
m_currentSize = dateTimeSize.height();
}
QString DateTimeDisplayer::getTimeString() const
{
return getTimeString(m_position);
// 如果日期时间的格式发生了变化,需要通知外部来调整日期时间的尺寸
if (lastSize != m_currentSize)
Q_EMIT requestUpdate();
}
bool DateTimeDisplayer::event(QEvent *event)
{
if (event->type() == QEvent::FontChange) {
m_dateFont = DFontSizeManager::instance()->t10();
m_timeFont = timeFont();
Q_EMIT requestUpdate();
} else if (event->type() == QEvent::Resize) {
m_dateFont = DFontSizeManager::instance()->t10();
m_timeFont = timeFont();
if (event->type() == QEvent::Resize) {
updateFont();
}
return QWidget::event(event);
}

View File

@ -13,10 +13,15 @@
#include <QWidget>
#include <QFont>
#include <dtkcore_global.h>
namespace Dock { class TipsWidget; }
class DockPopupWindow;
class QMenu;
DCORE_BEGIN_NAMESPACE
class DConfig;
DCORE_END_NAMESPACE
using Timedate = org::deepin::dde::Timedate1;
@ -57,16 +62,17 @@ private:
DateTimeInfo dateTimeInfo(const Dock::Position &position) const;
void updateLastData(const DateTimeInfo &info);
QString getTimeString() const;
inline QString getTimeString() const;
QString getTimeString(const Dock::Position &position) const;
QString getDateString() const;
inline QString getDateString() const;
QString getDateString(const Dock::Position &position) const;
QPoint tipsPoint() const;
QFont timeFont() const;
void updateFont() const;
void createMenuItem();
QRect textRect(const QRect &sourceRect) const;
void initDConfig();
private Q_SLOTS:
void onTimeChanged();
@ -87,7 +93,12 @@ private:
bool m_oneRow;
bool m_showMultiRow;
int m_shortDateFormat;
bool m_use24HourFormat;
DTK_CORE_NAMESPACE::DConfig *m_config;
QString m_shortDateFormatStr;
QString m_shortTimeFormatStr;
QString m_longDateFormatStr;
QString m_longTimeFormatStr;
QLocale m_locale;
};
#endif // DATETIMEDISPLAYER_H

View File

@ -38,9 +38,9 @@ DockTrayWindow::DockTrayWindow(QWidget *parent)
, m_dateTimeWidget(new DateTimeDisplayer(true, this))
, m_systemPuginWidget(new SystemPluginWindow(this))
, m_quickIconWidget(new QuickPluginWindow(Dock::DisplayMode::Efficient, this))
, m_trayView(new TrayGridView(this))
, m_trayView(TrayGridView::getDockTrayGridView(this))
, m_model(TrayModel::getDockModel())
, m_delegate(new TrayDelegate(m_trayView, this))
, m_delegate(TrayDelegate::getDockTrayDelegate(m_trayView, this))
, m_toolFrontSpaceWidget(new QWidget(this))
, m_toolBackSpaceWidget(new QWidget(this))
, m_dateTimeSpaceWidget(new QWidget(this))
@ -70,8 +70,16 @@ void DockTrayWindow::setDisplayMode(const Dock::DisplayMode &displayMode)
moveToolPlugin();
updateToolWidget();
// 如果当前模式为高效模式则设置当前的trayView为其计算位置的参照
if (displayMode == Dock::DisplayMode::Efficient)
if (displayMode == Dock::DisplayMode::Efficient) {
ExpandIconWidget::popupTrayView()->setReferGridView(m_trayView);
// TODO: reuse QuickPluginWindow, SystemPluginWindow
auto stretch = m_mainBoxLayout->takeAt(m_mainBoxLayout->count()-1);
m_mainBoxLayout->addWidget(m_trayView);
m_mainBoxLayout->addItem(stretch);
} else {
m_mainBoxLayout->removeWidget(m_trayView);
}
}
QSize DockTrayWindow::suitableSize(const Dock::Position &position, const int &, const double &) const

View File

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

View File

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

View File

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

View File

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

View File

@ -30,6 +30,24 @@
#include <xcb/xcb_icccm.h>
#include <X11/Xlib.h>
TrayDelegate *TrayDelegate::getDockTrayDelegate(QListView *view, QObject *parent)
{
static TrayDelegate *delegate = nullptr;
if (!delegate) {
delegate = new TrayDelegate(view, parent);
}
return delegate;
}
TrayDelegate *TrayDelegate::getIconTrayDelegate(QListView *view, QObject *parent)
{
static TrayDelegate *delegate = nullptr;
if (!delegate) {
delegate = new TrayDelegate(view, parent);
}
return delegate;
}
TrayDelegate::TrayDelegate(QListView *view, QObject *parent)
: QStyledItemDelegate(parent)
, m_position(Dock::Position::Bottom)

View File

@ -25,7 +25,9 @@ class TrayDelegate : public QStyledItemDelegate
Q_OBJECT
public:
explicit TrayDelegate(QListView *view, QObject *parent = nullptr);
static TrayDelegate *getDockTrayDelegate(QListView *view, QObject *parent = nullptr);
static TrayDelegate *getIconTrayDelegate(QListView *view, QObject *parent = nullptr);
void setPositon(Dock::Position position);
Q_SIGNALS:
@ -44,6 +46,8 @@ protected:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
private:
explicit TrayDelegate(QListView *view, QObject *parent = nullptr);
ExpandIconWidget *expandWidget();
bool isPopupTray() const;

View File

@ -20,6 +20,22 @@
#include <QDebug>
#include <QTimer>
TrayGridView *TrayGridView::getDockTrayGridView(QWidget *parent)
{
static TrayGridView *view = nullptr;
if (!view)
view = new TrayGridView(parent);
return view;
}
TrayGridView *TrayGridView::getIconTrayGridView(QWidget *parent)
{
static TrayGridView *view = nullptr;
if (!view)
view = new TrayGridView(parent);
return view;
}
TrayGridView::TrayGridView(QWidget *parent)
: DListView(parent)
, m_aniCurveType(QEasingCurve::Linear)
@ -35,7 +51,12 @@ TrayGridView::TrayGridView(QWidget *parent)
void TrayGridView::setPosition(Dock::Position position)
{
if (m_positon == position) {
return;
}
m_positon = position;
setOrientation(m_positon == Dock::Position::Top || m_positon == Dock::Position::Bottom ?
QListView::Flow::LeftToRight : QListView::Flow::TopToBottom, false);
}
Dock::Position TrayGridView::position() const
@ -308,7 +329,7 @@ void TrayGridView::dragLeaveEvent(QDragLeaveEvent *e)
{
m_aniStartTime->stop();
e->accept();
dragLeaved();
Q_EMIT dragLeaved();
}
void TrayGridView::dragMoveEvent(QDragMoveEvent *e)
@ -433,6 +454,15 @@ void TrayGridView::handleDropEvent(QDropEvent *e)
e->ignore();
DListView::dropEvent(e);
}
// 拖拽行为后会自动关闭Edtor导致托盘图标消失
QMetaObject::invokeMethod(this, [&] {
for (int i = 0; i < model()->rowCount(); i++) {
QModelIndex index = model()->index(i, 0);
if(!isPersistentEditorOpen(index)) {
openPersistentEditor(index);
}
}
}, Qt::QueuedConnection);
}
void TrayGridView::onUpdateEditorView()
@ -445,7 +475,7 @@ void TrayGridView::onUpdateEditorView()
// 因为closePersistentEditor后异步删除QWidget在关闭后如果立即调用openPersistentEditor在删除的时候会把
// 通过openPersistentEditor新建的QWidget给删除引起bug因此在所有的都closePersistentEditor后异步来调用
// openPersistentEditor就不会出现这种问题
QMetaObject::invokeMethod(this, [ = ] {
QMetaObject::invokeMethod(this, [&] {
for (int i = 0; i < model()->rowCount(); i++) {
QModelIndex index = model()->index(i, 0);
openPersistentEditor(index);

View File

@ -19,8 +19,9 @@ class TrayGridView : public DListView
Q_OBJECT
public:
explicit TrayGridView(QWidget *parent = Q_NULLPTR);
static TrayGridView *getDockTrayGridView(QWidget *parent = Q_NULLPTR);
static TrayGridView *getIconTrayGridView(QWidget *parent = Q_NULLPTR);
void setPosition(Dock::Position position);
Dock::Position position() const;
QSize suitableSize() const;
@ -58,6 +59,8 @@ protected:
bool beginDrag(Qt::DropActions supportedActions);
private:
explicit TrayGridView(QWidget *parent = Q_NULLPTR);
void initUi();
void createAnimation(const int pos, const bool moveNext, const bool isLastAni);
const QModelIndex getIndexFromPos(QPoint currentPoint) const;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,6 +4,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "expandiconwidget.h"
#include "taskmanager/taskmanager.h"
#include "tray_gridview.h"
#include "tray_model.h"
#include "tray_delegate.h"
@ -129,12 +130,12 @@ TrayGridWidget *ExpandIconWidget::popupTrayView()
return gridParentView;
gridParentView = new TrayGridWidget(nullptr);
TrayGridView *trayView = new TrayGridView(gridParentView);
TrayDelegate *trayDelegate = new TrayDelegate(trayView, trayView);
TrayGridView *trayView = TrayGridView::getIconTrayGridView(gridParentView);
TrayDelegate *trayDelegate = TrayDelegate::getIconTrayDelegate(trayView, trayView);
TrayModel *trayModel = TrayModel::getIconModel();
gridParentView->setTrayGridView(trayView);
gridParentView->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
gridParentView->setWindowFlags(Qt::WindowDoesNotAcceptFocus);
trayView->setModel(trayModel);
trayView->setItemDelegate(trayDelegate);
trayView->setSpacing(ITEM_SPACING);
@ -244,12 +245,16 @@ void TrayGridWidget::resetPosition()
void TrayGridWidget::showEvent(QShowEvent *event)
{
TaskManager::instance()->setTrayGridWidgetVisible(true);
TaskManager::instance()->updateHideState(true);
m_regionInter->registerRegion();
DBlurEffectWidget::showEvent(event);
}
void TrayGridWidget::hideEvent(QHideEvent *event)
{
TaskManager::instance()->setTrayGridWidgetVisible(false);
TaskManager::instance()->updateHideState(true);
m_regionInter->unregisterRegion();
// 在当前托盘区域隐藏后,需要设置任务栏区域的展开按钮的托盘为隐藏状态
TrayModel::getDockModel()->updateOpenExpand(false);

View File

@ -73,7 +73,6 @@ SNITrayItemWidget::SNITrayItemWidget(const QString &sniServicePath, QWidget *par
m_dbusPath = pair.second;
QDBusConnection conn = QDBusConnection::sessionBus();
setOwnerPID(conn.interface()->servicePid(m_dbusService));
m_sniInter = new StatusNotifierItem(m_dbusService, m_dbusPath, QDBusConnection::sessionBus(), this);
m_sniInter->setSync(false);
@ -797,7 +796,7 @@ bool SNITrayItemWidget::containsPoint(const QPoint &pos) {
}
// 如果菜单列表隐藏,则认为不在区域内
if (!m_menu->isVisible()) return false;
if (!m_menu || !m_menu->isVisible()) return false;
// 判断鼠标是否在菜单区域
return m_menu->geometry().contains(pos);

View File

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

View File

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

View File

@ -45,9 +45,9 @@ TrayManagerWindow::TrayManagerWindow(QWidget *parent)
, m_dateTimeWidget(new DateTimeDisplayer(false, m_appPluginDatetimeWidget))
, m_appPluginLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this))
, m_mainLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this))
, m_trayView(new TrayGridView(this))
, m_trayView(TrayGridView::getDockTrayGridView(this))
, m_model(TrayModel::getDockModel())
, m_delegate(new TrayDelegate(m_trayView, m_trayView))
, m_delegate(TrayDelegate::getDockTrayDelegate(m_trayView, m_trayView))
, m_position(Dock::Position::Bottom)
, m_displayMode(Dock::DisplayMode::Fashion)
, m_splitLine(new QLabel(m_appPluginDatetimeWidget))
@ -128,11 +128,6 @@ void TrayManagerWindow::setPositon(Dock::Position position)
m_position = position;
if (position == Dock::Position::Top || position == Dock::Position::Bottom)
m_trayView->setOrientation(QListView::Flow::LeftToRight, false);
else
m_trayView->setOrientation(QListView::Flow::TopToBottom, false);
TrayDelegate *delegate = static_cast<TrayDelegate *>(m_trayView->itemDelegate());
delegate->setPositon(position);
@ -151,6 +146,12 @@ void TrayManagerWindow::setDisplayMode(Dock::DisplayMode displayMode)
if (displayMode == Dock::DisplayMode::Fashion) {
ExpandIconWidget::popupTrayView()->setReferGridView(m_trayView);
updateItemLayout(m_windowFashionSize);
// TODO: reuse QuickPluginWindow, SystemPluginWindow
m_appPluginLayout->addWidget(TrayGridView::getDockTrayGridView());
m_appPluginLayout->addWidget(m_quickIconWidget);
} else {
m_appPluginLayout->removeWidget(TrayGridView::getDockTrayGridView());
m_appPluginLayout->removeWidget(m_quickIconWidget);
}
}
@ -176,7 +177,7 @@ int TrayManagerWindow::appDatetimeSize(const Dock::Position &position) const
int trayHeight = m_trayView->suitableSize(position).height();
int traypluginHeight = trayHeight + m_quickIconWidget->suitableSize(position).height() + m_appPluginLayout->spacing();
return traypluginHeight + m_dateTimeWidget->suitableSize(position).height() + 10;
return traypluginHeight + m_dateTimeWidget->suitableSize(position).height() + 2;
}
QSize TrayManagerWindow::suitableSize() const
@ -392,9 +393,8 @@ void TrayManagerWindow::resetChildWidgetSize()
int dateTimeHeight = m_appPluginDatetimeWidget->height() - - m.top() - m.bottom() - trayHeight;
m_dateTimeWidget->setFixedSize(dateTimeWidth, dateTimeHeight);
m_systemPluginWidget->setFixedSize(m_systemPluginWidget->suitableSize());
int contentSpace = qMin(MAXDIFF, qMax(((Utils::isDraging() ? height() : (int)m_windowFashionSize) - MINHIGHT), 0)) + MINSPACE;
m_mainLayout->setContentsMargins(contentSpace, contentSpace, contentSpace, contentSpace);
m_mainLayout->setSpacing(contentSpace);
m_mainLayout->setContentsMargins(SINGLEROWSPACE, SINGLEROWSPACE, SINGLEROWSPACE, SINGLEROWSPACE);
m_mainLayout->setSpacing(SINGLEROWSPACE);
// 调整插件和日期窗体的位置显示,这里没有用到布局,是因为在调整任务栏位置的时候,
// 随着布局方向的改变,显示有很大的问题
@ -536,8 +536,8 @@ void TrayManagerWindow::paintEvent(QPaintEvent *event)
painter.save();
painter.setRenderHint(QPainter::Antialiasing);
painter.setClipPath(path);
painter.fillRect(rect().adjusted(1, 1, -1, -1), maskColor(102));
painter.setPen(maskColor(110));
painter.fillRect(rect().adjusted(1, 1, -1, -1), maskColor(255 * 0.1));
painter.setPen(maskColor(255 * 0.15));
painter.drawPath(path);
painter.restore();

View File

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

View File

@ -1,4 +1,3 @@
#add_subdirectory("datetime")
add_subdirectory("shutdown")
add_subdirectory("power")
add_subdirectory("sound")
@ -13,3 +12,4 @@ add_subdirectory("show-desktop")
add_subdirectory("multitasking")
add_subdirectory("bluetooth")
add_subdirectory("airplane-mode")
add_subdirectory("notification")

View File

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

View File

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

View File

@ -39,6 +39,7 @@ void Adapter::addDevice(const QJsonObject &deviceObj)
const Device::State state = Device::State(deviceObj["State"].toInt());
const bool connectState = deviceObj["ConnectState"].toBool();
const QString bluetoothDeviceType = deviceObj["Icon"].toString();
const int battery = deviceObj["Battery"].toInt();
removeDevice(id);
@ -53,6 +54,7 @@ void Adapter::addDevice(const QJsonObject &deviceObj)
device->setRssi(rssi);
device->setAdapterId(m_id);
device->setDeviceType(bluetoothDeviceType);
device->setBattery(battery);
m_devices[id] = device;
@ -80,6 +82,7 @@ void Adapter::updateDevice(const QJsonObject &dviceJson)
const Device::State state = Device::State(dviceJson["State"].toInt());
const bool connectState = dviceJson["ConnectState"].toBool();
const QString bluetoothDeviceType = dviceJson["Icon"].toString();
const int battery = dviceJson["Battery"].toInt();
// FIXME: Solve the problem that the device name in the Bluetooth list is blank
if (name.isEmpty() && alias.isEmpty())
@ -97,6 +100,7 @@ void Adapter::updateDevice(const QJsonObject &dviceJson)
device->setConnectState(connectState);
device->setState(state);
device->setDeviceType(bluetoothDeviceType);
device->setBattery(battery);
emit deviceNameUpdated(device);
}
}
@ -123,6 +127,7 @@ void Adapter::initDevicesList(const QJsonDocument &doc)
const Device::State state = Device::State(deviceObj["State"].toInt());
const bool connectState = deviceObj["ConnectState"].toBool();
const QString bluetoothDeviceType = deviceObj["Icon"].toString();
const int battery = deviceObj["Battery"].toInt();
auto device = new Device(this);
device->setId(id);
@ -134,6 +139,7 @@ void Adapter::initDevicesList(const QJsonDocument &doc)
device->setRssi(rssi);
device->setAdapterId(adapterId);
device->setDeviceType(bluetoothDeviceType);
device->setBattery(battery);
m_devices[id] = device;
}

View File

@ -16,6 +16,7 @@
#include <DListView>
#include <DSpinner>
#include <DGuiApplicationHelper>
#include <DIconTheme>
#include <QBoxLayout>
#include <QStandardItemModel>
@ -27,6 +28,7 @@ BluetoothDeviceItem::BluetoothDeviceItem(QStyle *style, const Device *device, DL
, m_labelAction(nullptr)
, m_stateAction(nullptr)
, m_connAction(nullptr)
, m_batteryAction(nullptr)
, m_loading(new DSpinner(parent))
, m_iconWidget(new QWidget(parent->viewport()))
, m_connButton(new StateButton(m_iconWidget))
@ -53,6 +55,7 @@ void BluetoothDeviceItem::initActionList()
m_labelAction = new DViewItemAction(Qt::AlignLeft | Qt::AlignVCenter, QSize(), QSize(), false);
m_stateAction = new DViewItemAction(Qt::AlignLeft | Qt::AlignVCenter, QSize(), QSize(), true);
m_connAction = new DViewItemAction(Qt::AlignRight | Qt::AlignVCenter, QSize(16, 16), QSize(16, 16), false);
m_batteryAction = new DViewItemAction(Qt::AlignLeft | Qt::AlignVCenter, QSize(20, 20), QSize(20, 20), false);
m_connButton->setType(StateButton::Check);
m_connButton->setSwitchFork(true);
@ -69,16 +72,60 @@ void BluetoothDeviceItem::initActionList()
m_connAction->setWidget(m_iconWidget);
m_standarditem->setAccessibleText(m_device->alias());
m_standarditem->setActionList(Qt::RightEdge, { m_stateAction, m_connAction });
m_standarditem->setActionList(Qt::RightEdge, { m_batteryAction, m_stateAction, m_connAction });
m_standarditem->setActionList(Qt::LeftEdge, { m_labelAction });
//蓝牙列表可用蓝牙设备信息文字显示高亮
m_labelAction->setTextColorRole(DPalette::BrightText);
m_labelAction->setText(m_device->alias());
updateDeviceState(m_device->state());
m_batteryAction->setIcon(getBatteryIcon(m_device->battery()));
m_batteryAction->setVisible(m_device->battery() > 0);
updateIconTheme(DGuiApplicationHelper::instance()->themeType());
}
QIcon BluetoothDeviceItem::getBatteryIcon(int percentage)
{
/* 0-5%、6-10%、11%-20%、21-30%、31-40%、41-50%、51-60%、61%-70%、71-80%、81-90%、91-100% */
QString percentageStr;
if (percentage <= 5) {
percentageStr = "000";
} else if (percentage <= 10) {
percentageStr = "010";
} else if (percentage <= 20) {
percentageStr = "020";
} else if (percentage <= 30) {
percentageStr = "030";
} else if (percentage <= 40) {
percentageStr = "040";
} else if (percentage <= 50) {
percentageStr = "050";
} else if (percentage <= 60) {
percentageStr = "060";
} else if (percentage <= 70) {
percentageStr = "070";
} else if (percentage <= 80) {
percentageStr = "080";
} else if (percentage <= 90) {
percentageStr = "090";
} else if (percentage <= 100) {
percentageStr = "100";
} else {
percentageStr = "unknow";
}
QString iconName = QString("battery-%1-symbolic").arg(percentageStr);
auto themeType = DGuiApplicationHelper::instance()->themeType();
bool isDarkTheme = themeType == DGuiApplicationHelper::DarkType;
QString iconNameFallback = isDarkTheme ? iconName + "-dark" : iconName;
QIcon qrcIcon = DIconTheme::findQIcon(iconName, DIconTheme::DontFallbackToQIconFromTheme);
return DIconTheme::findQIcon(iconNameFallback, qrcIcon, DIconTheme::IgnoreBuiltinIcons);
}
void BluetoothDeviceItem::initConnect()
{
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &BluetoothDeviceItem::updateIconTheme);
@ -95,11 +142,17 @@ void BluetoothDeviceItem::updateIconTheme(DGuiApplicationHelper::ColorType type)
}
m_deviceIcon = type == DGuiApplicationHelper::LightType ? LightString.arg("other") : DarkString.arg("other");
m_labelAction->setIcon(QIcon::fromTheme(m_deviceIcon));
m_batteryAction->setIcon(getBatteryIcon(m_device->battery()));
}
void BluetoothDeviceItem::updateDeviceState(Device::State state)
{
m_labelAction->setText(m_device->alias());
m_batteryAction->setIcon(getBatteryIcon(m_device->battery()));
m_batteryAction->setVisible(m_device->battery() > 0);
if (state == Device::StateAvailable) {
m_loading->start();
m_stateAction->setVisible(true);
@ -184,6 +237,10 @@ void BluetoothAdapterItem::updateIconTheme(DGuiApplicationHelper::ColorType type
QSize BluetoothAdapterItem::sizeHint() const
{
// 没有 item 就不去做一些无效的计算了,包括分割线的高度
if (m_deviceListview->count() < 1)
return QSize(ItemWidth, m_adapterLabel->height());
int visualHeight = 0;
for (int i = 0; i < m_deviceListview->count(); i++)
visualHeight += m_deviceListview->visualRect(m_deviceModel->index(i, 0)).height();
@ -223,6 +280,10 @@ void BluetoothAdapterItem::initData()
void BluetoothAdapterItem::onDeviceAdded(const Device *device)
{
// 关闭蓝牙设备时,不再响应上一个扫描操作的新增的 device
if (!m_adapterStateBtn->isChecked())
return;
int insertRow = 0;
foreach (const auto item, m_deviceItems) {
if (item->device()->connectState()) {
@ -361,6 +422,8 @@ void BluetoothAdapterItem::initConnect()
m_seperator->setVisible(false);
m_adapterStateBtn->setEnabled(false);
m_refreshBtn->setVisible(state);
// FIX #6033 开启蓝牙就开始转动,关闭就停止转动
state ? m_refreshBtn->startRotate() : m_refreshBtn->stopRotate();
emit requestSetAdapterPower(m_adapter, state);
});
connect(m_bluetoothInter, &DBusBluetooth::DisplaySwitchChanged, this, [ = ](bool value) {

View File

@ -62,6 +62,7 @@ signals:
private:
void initActionList();
void initConnect();
QIcon getBatteryIcon(int percentage);
DStyleHelper m_style;
QString m_deviceIcon;
@ -71,6 +72,7 @@ private:
DViewItemAction *m_labelAction;
DViewItemAction *m_stateAction;
DViewItemAction *m_connAction;
DViewItemAction *m_batteryAction;
DSpinner *m_loading;
QWidget *m_iconWidget;

View File

@ -16,6 +16,7 @@ Device::Device(QObject *parent)
, m_rssi(0)
, m_state(StateUnavailable)
, m_connectState(false)
, m_battery(0)
{
}
@ -81,6 +82,14 @@ void Device::setDeviceType(const QString &deviceType)
m_deviceType = deviceType;
}
void Device::setBattery(int battery)
{
if (m_battery != battery) {
m_battery = battery;
Q_EMIT batteryChanged(battery);
}
}
QDebug &operator<<(QDebug &stream, const Device *device)
{
stream << "Device name:" << device->name()

View File

@ -56,6 +56,9 @@ public:
inline QString deviceType() const { return m_deviceType; }
void setDeviceType(const QString &deviceType);
inline int battery() const { return m_battery; }
void setBattery(int battery);
Q_SIGNALS:
void nameChanged(const QString &name) const;
void aliasChanged(const QString &alias) const;
@ -63,6 +66,7 @@ Q_SIGNALS:
void stateChanged(const State state) const;
void connectStateChanged(const bool connectState) const;
void rssiChanged(const int rssi) const;
void batteryChanged(const int battery) const;
private:
QString m_id;
@ -76,6 +80,7 @@ private:
bool m_connectState;
QString m_adapterId;
QString m_deviceType;
int m_battery;
};
QDebug &operator<<(QDebug &stream, const Device *device);

View File

@ -21,4 +21,32 @@
<file>dark/buletooth_other_dark.svg</file>
<file>light/buletooth_other_light.svg</file>
</qresource>
<qresource prefix="/icons/deepin/builtin">
<file>dark/icons/battery-000-symbolic_20px.svg</file>
<file>dark/icons/battery-010-symbolic_20px.svg</file>
<file>dark/icons/battery-020-symbolic_20px.svg</file>
<file>dark/icons/battery-030-symbolic_20px.svg</file>
<file>dark/icons/battery-040-symbolic_20px.svg</file>
<file>dark/icons/battery-050-symbolic_20px.svg</file>
<file>dark/icons/battery-060-symbolic_20px.svg</file>
<file>dark/icons/battery-070-symbolic_20px.svg</file>
<file>dark/icons/battery-080-symbolic_20px.svg</file>
<file>dark/icons/battery-090-symbolic_20px.svg</file>
<file>dark/icons/battery-100-symbolic_20px.svg</file>
<file>dark/icons/battery-unknow-symbolic_20px.svg</file>
<file>light/icons/battery-000-symbolic_20px.svg</file>
<file>light/icons/battery-010-symbolic_20px.svg</file>
<file>light/icons/battery-020-symbolic_20px.svg</file>
<file>light/icons/battery-030-symbolic_20px.svg</file>
<file>light/icons/battery-040-symbolic_20px.svg</file>
<file>light/icons/battery-050-symbolic_20px.svg</file>
<file>light/icons/battery-060-symbolic_20px.svg</file>
<file>light/icons/battery-070-symbolic_20px.svg</file>
<file>light/icons/battery-080-symbolic_20px.svg</file>
<file>light/icons/battery-090-symbolic_20px.svg</file>
<file>light/icons/battery-100-symbolic_20px.svg</file>
<file>light/icons/battery-unknow-symbolic_20px.svg</file>
<file alias="light/texts/bluetooth_16px.svg">light/buletooth_other_light.svg</file>
<file alias="dark/texts/bluetooth_16px.svg">dark/buletooth_other_dark.svg</file>
</qresource>
</RCC>

View File

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

After

Width:  |  Height:  |  Size: 586 B

View File

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

After

Width:  |  Height:  |  Size: 856 B

View File

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

After

Width:  |  Height:  |  Size: 862 B

View File

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

After

Width:  |  Height:  |  Size: 862 B

View File

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

After

Width:  |  Height:  |  Size: 861 B

View File

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

After

Width:  |  Height:  |  Size: 805 B

View File

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

After

Width:  |  Height:  |  Size: 805 B

View File

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

After

Width:  |  Height:  |  Size: 805 B

View File

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

After

Width:  |  Height:  |  Size: 865 B

View File

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

After

Width:  |  Height:  |  Size: 865 B

View File

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

After

Width:  |  Height:  |  Size: 925 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd">
<path fill="#FFF" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z" transform="translate(0 4)"/>
<path fill="#FFF" d="M7.24960955,9.17295223 C7.24960955,7.55198774 8.98558854,6.73505045 10.3818886,7.6117948 C10.9012329,7.93789395 10.8977923,8.94570718 10.4842054,9.30278852 C10.3726411,9.39911049 10.2473833,9.47583872 10.0333175,9.58418373 C9.975446,9.61330228 9.975446,9.61330228 9.91459846,9.64361911 C9.3945286,9.90299052 9.13632148,10.0754526 8.86329315,10.4241672 C8.54143819,10.8352436 8.49960955,11.0943269 8.49960955,12.1499222 L9.74960955,12.1499222 C9.74960955,11.3739441 9.76062141,11.3057375 9.84750825,11.1947648 C9.97325658,11.0341577 10.1089728,10.9435099 10.4724734,10.7622234 C10.5335228,10.7318093 10.5335228,10.7318093 10.5977966,10.6994699 C10.8949109,10.5490917 11.0963838,10.4256769 11.3010895,10.2489388 C12.3161432,9.37256501 12.3230323,7.35466185 11.0465976,6.55318158 C8.86860665,5.18560927 6,6.46427219 6,9.17295223 L7.24960955,9.17295223 Z M8.49960955,12.9008636 L9.74960955,12.9008636 L9.74960955,14.1508636 L8.49960955,14.1508636 L8.49960955,12.9008636 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

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

After

Width:  |  Height:  |  Size: 574 B

View File

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

After

Width:  |  Height:  |  Size: 856 B

View File

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

After

Width:  |  Height:  |  Size: 862 B

View File

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

After

Width:  |  Height:  |  Size: 862 B

View File

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

After

Width:  |  Height:  |  Size: 861 B

View File

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

After

Width:  |  Height:  |  Size: 805 B

View File

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

After

Width:  |  Height:  |  Size: 805 B

View File

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

After

Width:  |  Height:  |  Size: 805 B

View File

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

After

Width:  |  Height:  |  Size: 865 B

View File

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

After

Width:  |  Height:  |  Size: 865 B

View File

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

After

Width:  |  Height:  |  Size: 925 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<g fill="none" fill-rule="evenodd">
<path fill="#000" d="M15,-4.61852778e-14 C16.6568542,-4.61852778e-14 18,1.34314575 18,3 L18,9 C18,10.6568542 16.6568542,12 15,12 L3,12 C1.34314575,12 0,10.6568542 0,9 L0,3 C0,1.34314575 1.34314575,-4.61852778e-14 3,-4.61852778e-14 L15,-4.61852778e-14 Z M15,1 L3,1 C1.8954305,1 1,1.8954305 1,3 L1,9 C1,10.1045695 1.8954305,11 3,11 L15,11 C16.1045695,11 17,10.1045695 17,9 L17,3 C17,1.8954305 16.1045695,1 15,1 Z M20,3 L20,9 L19,9 L19,3 L20,3 Z" transform="translate(0 4)"/>
<path fill="#000" d="M7.24960955,9.17295223 C7.24960955,7.55198774 8.98558854,6.73505045 10.3818886,7.6117948 C10.9012329,7.93789395 10.8977923,8.94570718 10.4842054,9.30278852 C10.3726411,9.39911049 10.2473833,9.47583872 10.0333175,9.58418373 C9.975446,9.61330228 9.975446,9.61330228 9.91459846,9.64361911 C9.3945286,9.90299052 9.13632148,10.0754526 8.86329315,10.4241672 C8.54143819,10.8352436 8.49960955,11.0943269 8.49960955,12.1499222 L9.74960955,12.1499222 C9.74960955,11.3739441 9.76062141,11.3057375 9.84750825,11.1947648 C9.97325658,11.0341577 10.1089728,10.9435099 10.4724734,10.7622234 C10.5335228,10.7318093 10.5335228,10.7318093 10.5977966,10.6994699 C10.8949109,10.5490917 11.0963838,10.4256769 11.3010895,10.2489388 C12.3161432,9.37256501 12.3230323,7.35466185 11.0465976,6.55318158 C8.86860665,5.18560927 6,6.46427219 6,9.17295223 L7.24960955,9.17295223 Z M8.49960955,12.9008636 L9.74960955,12.9008636 L9.74960955,14.1508636 L8.49960955,14.1508636 L8.49960955,12.9008636 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

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