feat: 实现Apps服务、Launcher服务、Dock服务
*重写Apps服务,新服务分为org.deepin.daemon.DFWatcher1和org.deepin.daemon.ALRecorder1两个服务 *重写Launcher服务, 新服务名为org.deepin.dde.daemon.Launcher1 *重写Dock服务, 新服务名为org.deepin.dde.daemon.Dock1 *重写部分go-lib接口,保存在src/lib目录, 后续从项目中提出统一存放至开发库 *使用XCB库实现与XServer交互,存放在src/lib目录 *放弃依赖dde-qt-dbus-factory包, 将xml文件生成的静态编译代码存放在frameworkdbus目录 Log: 实现Apps服务、Launcher服务、Dock服务 Task: https://pms.uniontech.com/task-view-109315.html Influence: 无 Change-Id: Ia9676060bfe81ce8d02c48972cc3d3cbaf665a31
This commit is contained in:
parent
dd7d4737bf
commit
13a1cabda1
7
debian/control
vendored
7
debian/control
vendored
@ -10,6 +10,12 @@ Build-Depends:
|
||||
qt5-qmake,
|
||||
qtbase5-dev,
|
||||
qttools5-dev,
|
||||
libdtkcore-dev (>=5.4.14),
|
||||
libdtkcore5-bin (>=5.4.14),
|
||||
libxcb1-dev,
|
||||
libxcb-icccm4-dev,
|
||||
libxcb-ewmh-dev,
|
||||
libx11-dev,
|
||||
Standards-Version: 4.1.3
|
||||
Homepage: https://www.deepin.org
|
||||
|
||||
@ -20,3 +26,4 @@ Depends:
|
||||
${shlibs:Depends},
|
||||
Description: dde application manager module
|
||||
Application manager for DDE.
|
||||
|
||||
|
@ -1 +1,3 @@
|
||||
add_subdirectory(systemd)
|
||||
add_subdirectory(systemd)
|
||||
add_subdirectory(dconf)
|
||||
|
||||
|
7
misc/dconf/CMakeLists.txt
Normal file
7
misc/dconf/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
set(DCONFIG_FILES
|
||||
com.deepin.dde.launcher.json
|
||||
com.deepin.dde.dock.json
|
||||
com.deepin.dde.appearance.json
|
||||
)
|
||||
|
||||
install(FILES ${DCONFIG_FILES} DESTINATION /usr/share/dsg/configs/dde-application-manager)
|
145
misc/dconf/com.deepin.dde.appearance.json
Normal file
145
misc/dconf/com.deepin.dde.appearance.json
Normal file
@ -0,0 +1,145 @@
|
||||
{
|
||||
"magic": "dsg.config.meta",
|
||||
"version": "1.0",
|
||||
"contents": {
|
||||
"Extra_Picture_Uris": {
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Extra_Picture_Uris",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Font_Standard": {
|
||||
"value": "Noto Sans",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Font_Standard",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "The standard font for desktop",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Theme_Auto": {
|
||||
"value": false,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Theme_Auto",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Wallpaper_Slideshow": {
|
||||
"value": "",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Wallpaper_Slideshow",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Cursor_Theme": {
|
||||
"value": "bloom",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Cursor_Theme",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "Cursor theme name. Used only by Xservers that support the Xcursor extension.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Font_Size": {
|
||||
"value": 10.5,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Font_Size",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "The desktop font size",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Wallpaper_Uris": {
|
||||
"value": "",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Wallpaper_Uris",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "wallpaper json string",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Icon_Theme": {
|
||||
"value": "bloom",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Icon_Theme",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "Icon theme to use for the panel, nautilus etc.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Opacity": {
|
||||
"value": 0.40000000000000002,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Opacity",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Font_Monospace": {
|
||||
"value": "Noto Mono",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Font_Monospace",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "The monospace font for desktop",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Excluded_Icon_Themes": {
|
||||
"value": ["hicolor", "gnome", "Adwaita"],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Excluded_Icon_Themes",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "Icon theme black list.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Gtk_Theme": {
|
||||
"value": "deepin",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Gtk_Theme",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "Basename of the default theme used by gtk+.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Sound_Theme": {
|
||||
"value": "deepin",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Sound_Theme",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "Set the system sound theme",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Background_Uris": {
|
||||
"value": ["file:///usr/share/backgrounds/default_background.jpg"],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Background_Uris",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "Note that the backend only supports local (file://) URIs.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
}
|
||||
}
|
||||
}
|
146
misc/dconf/com.deepin.dde.dock.json
Normal file
146
misc/dconf/com.deepin.dde.dock.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"magic": "dsg.config.meta",
|
||||
"version": "1.0",
|
||||
"contents": {
|
||||
"Window_Size_Fashion": {
|
||||
"value": 48,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Window_Size_Fashion",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Icon_Size": {
|
||||
"value": 36,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Icon_Size",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Position": {
|
||||
"value": "bottom",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Position",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Wireless_Scan_Interval": {
|
||||
"value": 5,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Wireless_Scan_Interval",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "wireless scan interval",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Hide_Timeout": {
|
||||
"value": 0,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Hide_Timeout",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Hide_Mode": {
|
||||
"value": "keep-showing",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Hide_Mode",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "The value will influence when the dock is shown or hidden.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Show_Timeout": {
|
||||
"value": 100,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Show_Timeout",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Window_Size_Efficient": {
|
||||
"value": 40,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Window_Size_Efficient",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Plugin_Settings": {
|
||||
"value": "{}",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Plugin_Settings",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Docked_Apps": {
|
||||
"value": ["/S@dde-file-manager", "/S@uos-browser", "/S@org.deepin.browser", "/S@deepin-appstore", "/S@deepin-app-store", "/S@com.deepin.store.intranet", "/S@deepin-album", "/S@deepin-music", "/S@deepin-contacts", "/S@dde-calendar", "/S@dde-control-center"],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Docked_Apps",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "The default apps which is docked when dock is started.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Win_Icon_Preferred_Apps": {
|
||||
"value": ["apps.com.qq.im", "deepin.com.qq.im", "apps.com.qq.im.light", "apps.com.qq.b.eim", "apps.com.qq.rtxclient"],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Win_Icon_Preferred_Apps",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Delay_Plugins_Time": {
|
||||
"value": 0,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Delay_Plugins_Time",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Force_Quit_App": {
|
||||
"value": "enabled",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Force_Quit_App",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Display_Mode": {
|
||||
"value": "efficient",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Display_Mode",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "The dock gets different display mode, for instance, dock looks like win7 taskbar on classic mode.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
}
|
||||
}
|
||||
}
|
246
misc/dconf/com.deepin.dde.launcher.json
Normal file
246
misc/dconf/com.deepin.dde.launcher.json
Normal file
@ -0,0 +1,246 @@
|
||||
{
|
||||
"magic": "dsg.config.meta",
|
||||
"version": "1.0",
|
||||
"contents": {
|
||||
"Apps_Can_Not_Start_Up_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Can_Not_Start_Up_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps not allowed to start up",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Order_Zh_Cn": {
|
||||
"value": ["uos-browser", "org.deepin.browser", "dde-file-manager", "deepin-app-store", "deepin-appstore", "deepin-music", "deepin-movie", "deepin-screen-recorder", "deepin-image-viewer", "deepin-album", "deepin-draw", "deepin-reader", "deepin-editor", "deepin-mail", "thunderbird", "deepin-terminal", "terminal", "org.gnome.Terminal", "deepin-contacts", "deepin-voice-note", "downloader", "deepin-manual", "org.deepin.scanner", "org.deepin.scaner", "dde-computer", "dde-trash", "deepin-defender", "dde-control-center", "chineseime-setting", "fcitx-config-gtk3", "chineseime-setting-wizard", "deepin-system-monitor", "deepin-boot-maker", "deepin-devicemanager", "deepin-log-viewer", "dde-printer", "dde-calendar", "deepin-calculator", "deepin-font-manager", "deepin-compressor", "deepin-deb-installer", "deepin-diskmanager", "dde-introduction", "uos-service-support", "uos-remote-assistance", "deepin-camera", "deepin-phone-master", "gparted", "org.gnome.Cheese", "Cheese", "gnome.Cheese"],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Order_Zh_Cn",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "launcher apps order, ensure that all lowercase.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Icon_Ratio": {
|
||||
"value": 0.5,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Icon_Ratio",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "(null)",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Can_Not_Use_Proxy_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Can_Not_Use_Proxy_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps disable use proxy menu",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Hide_Start_Up_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Hide_Start_Up_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps hide function start up",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Fullscreen": {
|
||||
"value": false,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Fullscreen",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "(null)",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Mini_Frame_Right_Bar_Hide_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Mini_Frame_Right_Bar_Hide_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "icons not allowed to show on mini frame right bar",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Auto_Exit": {
|
||||
"value": false,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Auto_Exit",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "(null)",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Order_Zh_Tw": {
|
||||
"value": ["uos-browser", "org.deepin.browser", "dde-file-manager", "deepin-app-store", "deepin-appstore", "deepin-music", "deepin-movie", "deepin-screen-recorder", "deepin-image-viewer", "deepin-album", "deepin-draw", "deepin-reader", "deepin-editor", "deepin-mail", "thunderbird", "deepin-terminal", "terminal", "org.gnome.Terminal", "deepin-contacts", "deepin-voice-note", "downloader", "deepin-manual", "org.deepin.scanner", "org.deepin.scaner", "dde-computer", "dde-trash", "deepin-defender", "dde-control-center", "chineseime-setting", "fcitx-config-gtk3", "chineseime-setting-wizard", "deepin-system-monitor", "deepin-boot-maker", "deepin-devicemanager", "deepin-log-viewer", "dde-printer", "dde-calendar", "deepin-calculator", "deepin-font-manager", "deepin-compressor", "deepin-deb-installer", "deepin-diskmanager", "dde-introduction", "uos-service-support", "uos-remote-assistance", "deepin-camera", "deepin-phone-master", "gparted", "org.gnome.Cheese", "Cheese", "gnome.Cheese"],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Order_Zh_Tw",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "launcher apps order, ensure that all lowercase.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Can_Not_Send_To_Dock_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Can_Not_Send_To_Dock_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps not allowed to send to Dock",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Can_Not_Send_To_Desktop_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Can_Not_Send_To_Desktop_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps not allowed to send to Desktop",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Hide_Send_To_Desktop_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Hide_Send_To_Desktop_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps hide function send to desktop",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Hold_List": {
|
||||
"value": ["dde-introduction", "dde-file-manager", "deepin-appstore", "deepin-app-store", "deepin-terminal", "deepin-manual", "dde-computer", "dde-trash", "deepin-defender", "dde-control-center", "fcitx-config-gtk3", "fcitx-configtool", "deepin-system-monitor", "deepin-devicemanager", "dde-printer", "dde-calendar", "uos-service-support", "deepin-toggle-desktop", "deepin-wm-multitaskingview", "kwin-wm-multitaskingview", "com.deepin.store.intranet", "chineseime-setting"],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Hold_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps not allowed to uninstall",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Hide_Open_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Hide_Open_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps hide function open",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Can_Not_Open_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Can_Not_Open_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps not allowed to open",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Use_Proxy": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Use_Proxy",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Search_Package_Name": {
|
||||
"value": false,
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Search_Package_Name",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Order": {
|
||||
"value": ["uos-browser", "org.deepin.browser", "dde-file-manager", "deepin-app-store", "deepin-appstore", "deepin-music", "deepin-movie", "deepin-screen-recorder", "deepin-image-viewer", "deepin-album", "deepin-draw", "deepin-reader", "deepin-editor", "deepin-mail", "thunderbird", "deepin-terminal", "terminal", "org.gnome.Terminal", "deepin-contacts", "deepin-voice-note", "downloader", "deepin-manual", "org.deepin.scanner", "org.deepin.scaner", "dde-computer", "dde-trash", "deepin-defender", "dde-control-center", "chineseime-setting", "fcitx-config-gtk3", "chineseime-setting-wizard", "deepin-system-monitor", "deepin-boot-maker", "deepin-devicemanager", "deepin-log-viewer", "dde-printer", "dde-calendar", "deepin-calculator", "deepin-font-manager", "deepin-compressor", "deepin-deb-installer", "deepin-diskmanager", "dde-introduction", "uos-service-support", "uos-remote-assistance", "deepin-camera", "deepin-phone-master", "gparted", "org.gnome.Cheese", "Cheese", "gnome.Cheese"],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Order",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "launcher apps order, ensure that all lowercase.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Hide_Use_Proxy_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Hide_Use_Proxy_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps hide use proxy menu",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Disable_Scaling": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Disable_Scaling",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Hidden": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Hidden",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Hide_Send_To_Dock_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Hide_Send_To_Dock_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps hide function send to dock",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Apps_Hide_Uninstall_List": {
|
||||
"value": [],
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Apps_Hide_Uninstall_List",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "apps hide function uninstall",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
},
|
||||
"Display_Mode": {
|
||||
"value": "free",
|
||||
"serial": 0,
|
||||
"flags": ["global"],
|
||||
"name": "Display_Mode",
|
||||
"name[zh_CN]": "*****",
|
||||
"description": "Launcher display mode.",
|
||||
"permissions": "readwrite",
|
||||
"visibility": "private"
|
||||
}
|
||||
}
|
||||
}
|
73
src/frameworkdbus/dbusbamfapplication.cpp
Normal file
73
src/frameworkdbus/dbusbamfapplication.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c BamfApplication -p BamfApplication Application.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbusbamfapplication.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __BamfApplication
|
||||
*/
|
||||
|
||||
class __BamfApplicationPrivate
|
||||
{
|
||||
public:
|
||||
__BamfApplicationPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
__BamfApplication::__BamfApplication(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __BamfApplicationPrivate)
|
||||
{
|
||||
if (QMetaType::type("QList<uint>") == QMetaType::UnknownType) {
|
||||
qRegisterMetaType< QList<uint> >("QList<uint>");
|
||||
qDBusRegisterMetaType< QList<uint> >();
|
||||
}
|
||||
}
|
||||
|
||||
__BamfApplication::~__BamfApplication()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void __BamfApplication::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &__BamfApplication::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void __BamfApplication::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
134
src/frameworkdbus/dbusbamfapplication.h
Normal file
134
src/frameworkdbus/dbusbamfapplication.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c BamfApplication -p BamfApplication Application.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef BAMFAPPLICATION_H
|
||||
#define BAMFAPPLICATION_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.ayatana.bamf.application
|
||||
*/
|
||||
class __BamfApplicationPrivate;
|
||||
class __BamfApplication : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.ayatana.bamf.application"; }
|
||||
|
||||
public:
|
||||
explicit __BamfApplication(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~__BamfApplication();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline Q_DECL_DEPRECATED QDBusPendingReply<QString, QString> ApplicationMenu()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ApplicationMenu"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline Q_DECL_DEPRECATED QDBusReply<QString> ApplicationMenu(QString &objectpath)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
QDBusMessage reply = callWithArgumentList(QDBus::Block, QStringLiteral("ApplicationMenu"), argumentList);
|
||||
if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) {
|
||||
objectpath = qdbus_cast<QString>(reply.arguments().at(1));
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<QString> ApplicationType()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ApplicationType"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> DesktopFile()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("DesktopFile"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> FocusableChild()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("FocusableChild"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> ShowStubs()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ShowStubs"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> SupportedMimeTypes()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("SupportedMimeTypes"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QList<uint> > Xids()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Xids"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void DesktopFileUpdated(const QString &desktop_file);
|
||||
void SupportedMimeTypesChanged(const QStringList &dnd_mimes);
|
||||
Q_DECL_DEPRECATED void WindowAdded(const QString &path);
|
||||
Q_DECL_DEPRECATED void WindowRemoved(const QString &path);
|
||||
// begin property changed signals
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
|
||||
private:
|
||||
__BamfApplicationPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace org {
|
||||
namespace ayatana {
|
||||
namespace bamf {
|
||||
typedef ::__BamfApplication BamfApplication;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
75
src/frameworkdbus/dbusbamfmatcher.cpp
Normal file
75
src/frameworkdbus/dbusbamfmatcher.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c BamfMatcher -p BamfMatcher Matcher.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbusbamfmatcher.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __BamfMatcher
|
||||
*/
|
||||
|
||||
class __BamfMatcherPrivate
|
||||
{
|
||||
public:
|
||||
__BamfMatcherPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
__BamfMatcher::__BamfMatcher(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __BamfMatcherPrivate)
|
||||
{
|
||||
if (QMetaType::type("QList<uint>") == QMetaType::UnknownType) {
|
||||
qRegisterMetaType< QList<uint> >("QList<uint>");
|
||||
qDBusRegisterMetaType< QList<uint> >();
|
||||
}
|
||||
}
|
||||
|
||||
__BamfMatcher::~__BamfMatcher()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void __BamfMatcher::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &__BamfMatcher::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void __BamfMatcher::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
if (callName.isEmpty())
|
||||
return;
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
188
src/frameworkdbus/dbusbamfmatcher.h
Normal file
188
src/frameworkdbus/dbusbamfmatcher.h
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c BamfMatcher -p BamfMatcher Matcher.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef BAMFMATCHER_H
|
||||
#define BAMFMATCHER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.ayatana.bamf.matcher
|
||||
*/
|
||||
class __BamfMatcherPrivate;
|
||||
class __BamfMatcher : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.ayatana.bamf.matcher"; }
|
||||
|
||||
public:
|
||||
explicit __BamfMatcher(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~__BamfMatcher();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<QString> ActiveApplication()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ActiveApplication"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> ActiveWindow()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> ApplicationForXid(uint xid)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(xid);
|
||||
return asyncCallWithArgumentList(QStringLiteral("ApplicationForXid"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> ApplicationIsRunning(const QString &desktop_file)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(desktop_file);
|
||||
return asyncCallWithArgumentList(QStringLiteral("ApplicationIsRunning"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> ApplicationPaths()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ApplicationPaths"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> PathForApplication(const QString &desktop_file)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(desktop_file);
|
||||
return asyncCallWithArgumentList(QStringLiteral("PathForApplication"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RegisterFavorites(const QStringList &favorites)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(favorites);
|
||||
return asyncCallWithArgumentList(QStringLiteral("RegisterFavorites"), argumentList);
|
||||
}
|
||||
|
||||
inline void RegisterFavoritesQueued(const QStringList &favorites)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(favorites);
|
||||
|
||||
CallQueued(QStringLiteral("RegisterFavorites"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> RunningApplications()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RunningApplications"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> RunningApplicationsDesktopFiles()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RunningApplicationsDesktopFiles"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> TabPaths()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("TabPaths"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> WindowPaths()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("WindowPaths"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> WindowStackForMonitor(int monitor_id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(monitor_id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("WindowStackForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QList<uint> > XidsForApplication(const QString &desktop_file)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(desktop_file);
|
||||
return asyncCallWithArgumentList(QStringLiteral("XidsForApplication"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void ActiveApplicationChanged(const QString &old_app, const QString &new_app);
|
||||
void ActiveWindowChanged(const QString &old_win, const QString &new_win);
|
||||
void RunningApplicationsChanged(const QStringList &opened_desktop_files, const QStringList &closed_desktop_files);
|
||||
void StackingOrderChanged();
|
||||
void ViewClosed(const QString &path, const QString &type);
|
||||
void ViewOpened(const QString &path, const QString &type);
|
||||
// begin property changed signals
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
|
||||
private:
|
||||
__BamfMatcherPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace org {
|
||||
namespace ayatana {
|
||||
namespace bamf {
|
||||
typedef ::__BamfMatcher BamfMatcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
71
src/frameworkdbus/dbuskwaylandoutput.cpp
Normal file
71
src/frameworkdbus/dbuskwaylandoutput.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c OutputManagement -p generated/outputmanagement ../xml/OutputManagement.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbuskwaylandoutput.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __OutputManagement
|
||||
*/
|
||||
|
||||
class __OutputManagementPrivate
|
||||
{
|
||||
public:
|
||||
__OutputManagementPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
__OutputManagement::__OutputManagement(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __OutputManagementPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
__OutputManagement::~__OutputManagement()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void __OutputManagement::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &__OutputManagement::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void __OutputManagement::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
if (callName.isEmpty())
|
||||
return;
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
119
src/frameworkdbus/dbuskwaylandoutput.h
Normal file
119
src/frameworkdbus/dbuskwaylandoutput.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c OutputManagement -p generated/outputmanagement ../xml/OutputManagement.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef OUTPUTMANAGEMENT_H
|
||||
#define OUTPUTMANAGEMENT_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
|
||||
/*
|
||||
* Proxy class for interface com.deepin.daemon.KWayland.Output
|
||||
*/
|
||||
class __OutputManagementPrivate;
|
||||
class __OutputManagement : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "com.deepin.daemon.KWayland.Output"; }
|
||||
|
||||
public:
|
||||
explicit __OutputManagement(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~__OutputManagement();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> Apply(const QString &outputs)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(outputs);
|
||||
return asyncCallWithArgumentList(QStringLiteral("Apply"), argumentList);
|
||||
}
|
||||
|
||||
inline void ApplyQueued(const QString &outputs)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(outputs);
|
||||
|
||||
CallQueued(QStringLiteral("Apply"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> GetOutput(const QString &uuid)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uuid);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetOutput"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> ListOutput()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ListOutput"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> WlSimulateKey(int state)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(state);
|
||||
return asyncCallWithArgumentList(QStringLiteral("WlSimulateKey"), argumentList);
|
||||
}
|
||||
|
||||
inline void WlSimulateKeyQueued(int state)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(state);
|
||||
|
||||
CallQueued(QStringLiteral("WlSimulateKey"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void OutputAdded(const QString &output);
|
||||
void OutputChanged(const QString &output);
|
||||
void OutputRemoved(const QString &output);
|
||||
// begin property changed signals
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
|
||||
private:
|
||||
__OutputManagementPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace com {
|
||||
namespace deepin {
|
||||
namespace daemon {
|
||||
namespace kwayland {
|
||||
typedef ::__OutputManagement Output;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
71
src/frameworkdbus/dbuskwaylandwindowmanager.cpp
Normal file
71
src/frameworkdbus/dbuskwaylandwindowmanager.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c kwaylandmanager -p kwaylandmanager com.deepin.daemon.KWayland.WindowManager.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbuskwaylandwindowmanager.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __kwaylandmanager
|
||||
*/
|
||||
|
||||
class __kwaylandmanagerPrivate
|
||||
{
|
||||
public:
|
||||
__kwaylandmanagerPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
__KwaylandManager::__KwaylandManager(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __kwaylandmanagerPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
__KwaylandManager::~__KwaylandManager()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void __KwaylandManager::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &__KwaylandManager::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void __KwaylandManager::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
if (callName.isEmpty())
|
||||
return;
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
94
src/frameworkdbus/dbuskwaylandwindowmanager.h
Normal file
94
src/frameworkdbus/dbuskwaylandwindowmanager.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c kwaylandmanager -p kwaylandmanager com.deepin.daemon.KWayland.WindowManager.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef KWAYLANDMANAGER_H
|
||||
#define KWAYLANDMANAGER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
|
||||
/*
|
||||
* Proxy class for interface com.deepin.daemon.KWayland.WindowManager
|
||||
*/
|
||||
class __kwaylandmanagerPrivate;
|
||||
class __KwaylandManager : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "com.deepin.daemon.KWayland.WindowManager"; }
|
||||
|
||||
public:
|
||||
explicit __KwaylandManager(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~__KwaylandManager();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<uint> ActiveWindow()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsShowingDesktop()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsShowingDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QVariantList> Windows()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Windows"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void ActiveWindowChanged();
|
||||
void WindowCreated(const QString &ObjPath);
|
||||
void WindowRemove(const QString &ObjPath);
|
||||
// begin property changed signals
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
|
||||
private:
|
||||
__kwaylandmanagerPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace com {
|
||||
namespace deepin {
|
||||
namespace daemon {
|
||||
namespace kwayland {
|
||||
typedef ::__KwaylandManager WindowManager;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
129
src/frameworkdbus/dbuslauncher.cpp
Normal file
129
src/frameworkdbus/dbuslauncher.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c Launcherd -p generated/com_deepin_dde_daemon_launcherd ../xml/com.deepin.dde.daemon.Launcherd.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbuslauncher.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __Launcherd
|
||||
*/
|
||||
|
||||
class __LauncherdPrivate
|
||||
{
|
||||
public:
|
||||
__LauncherdPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
int DisplayMode;
|
||||
bool Fullscreen;
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
LauncherBackEnd::LauncherBackEnd(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __LauncherdPrivate)
|
||||
{
|
||||
connect(this, &LauncherBackEnd::propertyChanged, this, &LauncherBackEnd::onPropertyChanged);
|
||||
|
||||
if (QMetaType::type("LauncherItemInfo") == QMetaType::UnknownType)
|
||||
registerLauncherItemInfoMetaType();
|
||||
if (QMetaType::type("LauncherItemInfoList") == QMetaType::UnknownType)
|
||||
registerLauncherItemInfoListMetaType();
|
||||
}
|
||||
|
||||
LauncherBackEnd::~LauncherBackEnd()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void LauncherBackEnd::onPropertyChanged(const QString &propName, const QVariant &value)
|
||||
{
|
||||
if (propName == QStringLiteral("DisplayMode"))
|
||||
{
|
||||
const int &DisplayMode = qvariant_cast<int>(value);
|
||||
if (d_ptr->DisplayMode != DisplayMode)
|
||||
{
|
||||
d_ptr->DisplayMode = DisplayMode;
|
||||
Q_EMIT DisplayModeChanged(d_ptr->DisplayMode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (propName == QStringLiteral("Fullscreen"))
|
||||
{
|
||||
const bool &Fullscreen = qvariant_cast<bool>(value);
|
||||
if (d_ptr->Fullscreen != Fullscreen)
|
||||
{
|
||||
d_ptr->Fullscreen = Fullscreen;
|
||||
Q_EMIT FullscreenChanged(d_ptr->Fullscreen);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
qWarning() << "property not handle: " << propName;
|
||||
return;
|
||||
}
|
||||
|
||||
int LauncherBackEnd::displayMode()
|
||||
{
|
||||
return qvariant_cast<int>(internalPropGet("DisplayMode", &d_ptr->DisplayMode));
|
||||
}
|
||||
|
||||
void LauncherBackEnd::setDisplayMode(int value)
|
||||
{
|
||||
|
||||
internalPropSet("DisplayMode", QVariant::fromValue(value), &d_ptr->DisplayMode);
|
||||
}
|
||||
|
||||
bool LauncherBackEnd::fullscreen()
|
||||
{
|
||||
return qvariant_cast<bool>(internalPropGet("Fullscreen", &d_ptr->Fullscreen));
|
||||
}
|
||||
|
||||
void LauncherBackEnd::setFullscreen(bool value)
|
||||
{
|
||||
|
||||
internalPropSet("Fullscreen", QVariant::fromValue(value), &d_ptr->Fullscreen);
|
||||
}
|
||||
|
||||
void LauncherBackEnd::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &LauncherBackEnd::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherBackEnd::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
if (callName.isEmpty())
|
||||
return;
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
235
src/frameworkdbus/dbuslauncher.h
Normal file
235
src/frameworkdbus/dbuslauncher.h
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c Launcherd -p generated/com_deepin_dde_daemon_launcherd ../xml/com.deepin.dde.daemon.Launcherd.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef COM_DEEPIN_DDE_DAEMON_LAUNCHERD_H
|
||||
#define COM_DEEPIN_DDE_DAEMON_LAUNCHERD_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include "types/launcheriteminfo.h"
|
||||
#include "types/launcheriteminfolist.h"
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.deepin.dde.daemon.Launcher1
|
||||
*/
|
||||
class __LauncherdPrivate;
|
||||
class LauncherBackEnd : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.deepin.dde.daemon.Launcher1"; }
|
||||
|
||||
public:
|
||||
explicit LauncherBackEnd(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~LauncherBackEnd();
|
||||
|
||||
Q_PROPERTY(int DisplayMode READ displayMode WRITE setDisplayMode NOTIFY DisplayModeChanged)
|
||||
int displayMode();
|
||||
void setDisplayMode(int value);
|
||||
|
||||
Q_PROPERTY(bool Fullscreen READ fullscreen WRITE setFullscreen NOTIFY FullscreenChanged)
|
||||
bool fullscreen();
|
||||
void setFullscreen(bool value);
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<LauncherItemInfoList> GetAllItemInfos()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetAllItemInfos"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> GetAllNewInstalledApps()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetAllNewInstalledApps"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> GetDisableScaling(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetDisableScaling"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<LauncherItemInfo> GetItemInfo(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetItemInfo"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> GetUseProxy(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetUseProxy"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsItemOnDesktop(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsItemOnDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> MarkLaunched(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("MarkLaunched"), argumentList);
|
||||
}
|
||||
|
||||
inline void MarkLaunchedQueued(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
|
||||
CallQueued(QStringLiteral("MarkLaunched"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> RequestRemoveFromDesktop(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestRemoveFromDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> RequestSendToDesktop(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestSendToDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestUninstall(const QString &id, bool purge)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id) << QVariant::fromValue(purge);
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestUninstall"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestUninstallQueued(const QString &id, bool purge)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id) << QVariant::fromValue(purge);
|
||||
|
||||
CallQueued(QStringLiteral("RequestUninstall"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> Search(const QString &key)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(key);
|
||||
return asyncCallWithArgumentList(QStringLiteral("Search"), argumentList);
|
||||
}
|
||||
|
||||
inline void SearchQueued(const QString &key)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(key);
|
||||
|
||||
CallQueued(QStringLiteral("Search"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetDisableScaling(const QString &id, bool value)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id) << QVariant::fromValue(value);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetDisableScaling"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetDisableScalingQueued(const QString &id, bool value)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id) << QVariant::fromValue(value);
|
||||
|
||||
CallQueued(QStringLiteral("SetDisableScaling"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetUseProxy(const QString &id, bool value)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id) << QVariant::fromValue(value);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetUseProxy"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetUseProxyQueued(const QString &id, bool value)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id) << QVariant::fromValue(value);
|
||||
|
||||
CallQueued(QStringLiteral("SetUseProxy"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void ItemChanged(const QString &status, LauncherItemInfo itemInfo, qlonglong categoryID);
|
||||
void NewAppLaunched(const QString &appID);
|
||||
void SearchDone(const QStringList &apps);
|
||||
void UninstallFailed(const QString &appId, const QString &errMsg);
|
||||
void UninstallSuccess(const QString &appID);
|
||||
// begin property changed signals
|
||||
void DisplayModeChanged(int value) const;
|
||||
void FullscreenChanged(bool value) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
void onPropertyChanged(const QString &propName, const QVariant &value);
|
||||
|
||||
private:
|
||||
__LauncherdPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace com {
|
||||
namespace deepin {
|
||||
namespace dde {
|
||||
namespace daemon {
|
||||
typedef ::LauncherBackEnd LauncherBackEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
96
src/frameworkdbus/dbuslauncherfront.cpp
Normal file
96
src/frameworkdbus/dbuslauncherfront.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c Launcher -p generated/com_deepin_dde_launcher ../xml/com.deepin.dde.Launcher.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbuslauncherfront.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __Launcher
|
||||
*/
|
||||
|
||||
class __LauncherPrivate
|
||||
{
|
||||
public:
|
||||
__LauncherPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
bool Visible;
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
LauncherFront::LauncherFront(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __LauncherPrivate)
|
||||
{
|
||||
connect(this, &LauncherFront::propertyChanged, this, &LauncherFront::onPropertyChanged);
|
||||
|
||||
}
|
||||
|
||||
LauncherFront::~LauncherFront()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void LauncherFront::onPropertyChanged(const QString &propName, const QVariant &value)
|
||||
{
|
||||
if (propName == QStringLiteral("Visible"))
|
||||
{
|
||||
const bool &Visible = qvariant_cast<bool>(value);
|
||||
if (d_ptr->Visible != Visible)
|
||||
{
|
||||
d_ptr->Visible = Visible;
|
||||
Q_EMIT VisibleChanged(d_ptr->Visible);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
qWarning() << "property not handle: " << propName;
|
||||
return;
|
||||
}
|
||||
|
||||
bool LauncherFront::visible()
|
||||
{
|
||||
return qvariant_cast<bool>(internalPropGet("Visible", &d_ptr->Visible));
|
||||
}
|
||||
|
||||
void LauncherFront::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &LauncherFront::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherFront::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
if (callName.isEmpty())
|
||||
return;
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
169
src/frameworkdbus/dbuslauncherfront.h
Normal file
169
src/frameworkdbus/dbuslauncherfront.h
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c Launcher -p generated/com_deepin_dde_launcher ../xml/com.deepin.dde.Launcher.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef COM_DEEPIN_DDE_LAUNCHER_H
|
||||
#define COM_DEEPIN_DDE_LAUNCHER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.deepin.dde.Launcher1
|
||||
*/
|
||||
class __LauncherPrivate;
|
||||
class LauncherFront : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.deepin.dde.Launcher1"; }
|
||||
|
||||
public:
|
||||
explicit LauncherFront(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~LauncherFront();
|
||||
|
||||
Q_PROPERTY(bool Visible READ visible NOTIFY VisibleChanged)
|
||||
bool visible();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> Exit()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Exit"), argumentList);
|
||||
}
|
||||
|
||||
inline void ExitQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("Exit"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> Hide()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Hide"), argumentList);
|
||||
}
|
||||
|
||||
inline void HideQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("Hide"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsVisible()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsVisible"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> Show()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Show"), argumentList);
|
||||
}
|
||||
|
||||
inline void ShowQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("Show"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> ShowByMode(qlonglong in0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(in0);
|
||||
return asyncCallWithArgumentList(QStringLiteral("ShowByMode"), argumentList);
|
||||
}
|
||||
|
||||
inline void ShowByModeQueued(qlonglong in0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(in0);
|
||||
|
||||
CallQueued(QStringLiteral("ShowByMode"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> Toggle()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Toggle"), argumentList);
|
||||
}
|
||||
|
||||
inline void ToggleQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("Toggle"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> UninstallApp(const QString &appKey)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(appKey);
|
||||
return asyncCallWithArgumentList(QStringLiteral("UninstallApp"), argumentList);
|
||||
}
|
||||
|
||||
inline void UninstallAppQueued(const QString &appKey)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(appKey);
|
||||
|
||||
CallQueued(QStringLiteral("UninstallApp"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void Closed();
|
||||
void Shown();
|
||||
void VisibleChanged(bool visible);
|
||||
// begin property changed signals
|
||||
//void VisibleChanged(bool value) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
void onPropertyChanged(const QString &propName, const QVariant &value);
|
||||
|
||||
private:
|
||||
__LauncherPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace com {
|
||||
namespace deepin {
|
||||
namespace dde {
|
||||
typedef ::LauncherFront LauncherFront;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
73
src/frameworkdbus/dbusplasmawindow.cpp
Normal file
73
src/frameworkdbus/dbusplasmawindow.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c Window -p generated/window ../xml/Window.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbusplasmawindow.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __Window
|
||||
*/
|
||||
|
||||
class __WindowPrivate
|
||||
{
|
||||
public:
|
||||
__WindowPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
PlasmaWindow::PlasmaWindow(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __WindowPrivate)
|
||||
{
|
||||
if (QMetaType::type("Rect") == QMetaType::UnknownType)
|
||||
registerRectMetaType();
|
||||
}
|
||||
|
||||
PlasmaWindow::~PlasmaWindow()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void PlasmaWindow::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &PlasmaWindow::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void PlasmaWindow::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
if (callName.isEmpty())
|
||||
return;
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
499
src/frameworkdbus/dbusplasmawindow.h
Normal file
499
src/frameworkdbus/dbusplasmawindow.h
Normal file
@ -0,0 +1,499 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c Window -p generated/window ../xml/Window.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include "types/rect.h"
|
||||
|
||||
/*
|
||||
* Proxy class for interface com.deepin.daemon.KWayland.PlasmaWindow
|
||||
*/
|
||||
class __WindowPrivate;
|
||||
class PlasmaWindow : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "com.deepin.daemon.KWayland.PlasmaWindow"; }
|
||||
|
||||
public:
|
||||
explicit PlasmaWindow(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~PlasmaWindow();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<QString> AppId()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("AppId"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<Rect> Geometry()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Geometry"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> Icon()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Icon"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<uint> InternalId()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("InternalId"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsActive()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsActive"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsCloseable()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsCloseable"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsDemandingAttention()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsDemandingAttention"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsFullscreen()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsFullscreen"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsFullscreenable()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsFullscreenable"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsKeepAbove()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsKeepAbove"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsMaximizeable()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsMaximizeable"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsMaximized()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsMaximized"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsMinimizeable()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsMinimizeable"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsMinimized()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsMinimized"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsMovable()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsMovable"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsOnAllDesktops()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsOnAllDesktops"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsResizable()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsResizable"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsShadeable()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsShadeable"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsShaded()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsShaded"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsValid()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsValid"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> IsVirtualDesktopChangeable()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("IsVirtualDesktopChangeable"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<uint> Pid()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Pid"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestActivate()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestActivate"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestActivateQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestActivate"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestClose()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestClose"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestCloseQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestClose"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestEnterNewVirtualDesktop()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestEnterNewVirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestEnterNewVirtualDesktopQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestEnterNewVirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestEnterVirtualDesktop(const QString &argin0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(argin0);
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestEnterVirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestEnterVirtualDesktopQueued(const QString &argin0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(argin0);
|
||||
|
||||
CallQueued(QStringLiteral("RequestEnterVirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestLeaveVirtualDesktop(const QString &argin0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(argin0);
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestLeaveVirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestLeaveVirtualDesktopQueued(const QString &argin0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(argin0);
|
||||
|
||||
CallQueued(QStringLiteral("RequestLeaveVirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestMove()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestMove"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestMoveQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestMove"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestResize()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestResize"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestResizeQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestResize"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestToggleKeepAbove()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestToggleKeepAbove"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestToggleKeepAboveQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestToggleKeepAbove"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestToggleKeepBelow()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestToggleKeepBelow"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestToggleKeepBelowQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestToggleKeepBelow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestToggleMaximized()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestToggleMaximized"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestToggleMaximizedQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestToggleMaximized"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestToggleMinimized()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestToggleMinimized"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestToggleMinimizedQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestToggleMinimized"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestToggleShaded()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestToggleShaded"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestToggleShadedQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestToggleShaded"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestVirtualDesktop(uint argin0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(argin0);
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestVirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestVirtualDesktopQueued(uint argin0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(argin0);
|
||||
|
||||
CallQueued(QStringLiteral("RequestVirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> SkipSwitcher()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("SkipSwitcher"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> SkipTaskbar()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("SkipTaskbar"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> Title()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Title"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<uint> VirtualDesktop()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("VirtualDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<uint> WindowId()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("WindowId"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void ActiveChanged();
|
||||
void AppIdChanged();
|
||||
void CloseableChanged();
|
||||
void DemandsAttentionChanged();
|
||||
void FullscreenChanged();
|
||||
void FullscreenableChanged();
|
||||
void GeometryChanged();
|
||||
void IconChanged();
|
||||
void KeepAboveChanged();
|
||||
void KeepBelowChanged();
|
||||
void MaximizeableChanged();
|
||||
void MaximizedChanged();
|
||||
void MinimizeableChanged();
|
||||
void MinimizedChanged();
|
||||
void MovableChanged();
|
||||
void OnAllDesktopsChanged();
|
||||
void ParentWindowChanged();
|
||||
void ResizableChanged();
|
||||
void ShadeableChanged();
|
||||
void ShadedChanged();
|
||||
void SkipSwitcherChanged();
|
||||
void SkipTaskbarChanged();
|
||||
void TitleChanged();
|
||||
void Unmapped();
|
||||
void VirtualDesktopChangeableChanged();
|
||||
void VirtualDesktopChanged();
|
||||
void WindowIdChanged();
|
||||
// begin property changed signals
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
|
||||
private:
|
||||
__WindowPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace com {
|
||||
namespace deepin {
|
||||
namespace daemon {
|
||||
namespace kwayland {
|
||||
typedef ::PlasmaWindow PlasmaWindow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
209
src/frameworkdbus/dbuswm.cpp
Normal file
209
src/frameworkdbus/dbuswm.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c wm -p generated/com_deepin_wm ../xml/com.deepin.wm.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbuswm.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __wm
|
||||
*/
|
||||
|
||||
class __wmPrivate
|
||||
{
|
||||
public:
|
||||
__wmPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
bool compositingAllowSwitch;
|
||||
bool compositingEnabled;
|
||||
bool compositingPossible;
|
||||
int cursorSize;
|
||||
QString cursorTheme;
|
||||
bool zoneEnabled;
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
__wm::__wm(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __wmPrivate)
|
||||
{
|
||||
connect(this, &__wm::propertyChanged, this, &__wm::onPropertyChanged);
|
||||
|
||||
if (QMetaType::type("QList<uint>") == QMetaType::UnknownType) {
|
||||
qRegisterMetaType< QList<uint> >("QList<uint>");
|
||||
qDBusRegisterMetaType< QList<uint> >();
|
||||
}
|
||||
}
|
||||
|
||||
__wm::~__wm()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void __wm::onPropertyChanged(const QString &propName, const QVariant &value)
|
||||
{
|
||||
if (propName == QStringLiteral("compositingAllowSwitch"))
|
||||
{
|
||||
const bool &compositingAllowSwitch = qvariant_cast<bool>(value);
|
||||
if (d_ptr->compositingAllowSwitch != compositingAllowSwitch)
|
||||
{
|
||||
d_ptr->compositingAllowSwitch = compositingAllowSwitch;
|
||||
Q_EMIT CompositingAllowSwitchChanged(d_ptr->compositingAllowSwitch);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (propName == QStringLiteral("compositingEnabled"))
|
||||
{
|
||||
const bool &compositingEnabled = qvariant_cast<bool>(value);
|
||||
if (d_ptr->compositingEnabled != compositingEnabled)
|
||||
{
|
||||
d_ptr->compositingEnabled = compositingEnabled;
|
||||
Q_EMIT CompositingEnabledChanged(d_ptr->compositingEnabled);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (propName == QStringLiteral("compositingPossible"))
|
||||
{
|
||||
const bool &compositingPossible = qvariant_cast<bool>(value);
|
||||
if (d_ptr->compositingPossible != compositingPossible)
|
||||
{
|
||||
d_ptr->compositingPossible = compositingPossible;
|
||||
Q_EMIT CompositingPossibleChanged(d_ptr->compositingPossible);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (propName == QStringLiteral("cursorSize"))
|
||||
{
|
||||
const int &cursorSize = qvariant_cast<int>(value);
|
||||
if (d_ptr->cursorSize != cursorSize)
|
||||
{
|
||||
d_ptr->cursorSize = cursorSize;
|
||||
Q_EMIT CursorSizeChanged(d_ptr->cursorSize);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (propName == QStringLiteral("cursorTheme"))
|
||||
{
|
||||
const QString &cursorTheme = qvariant_cast<QString>(value);
|
||||
if (d_ptr->cursorTheme != cursorTheme)
|
||||
{
|
||||
d_ptr->cursorTheme = cursorTheme;
|
||||
Q_EMIT CursorThemeChanged(d_ptr->cursorTheme);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (propName == QStringLiteral("zoneEnabled"))
|
||||
{
|
||||
const bool &zoneEnabled = qvariant_cast<bool>(value);
|
||||
if (d_ptr->zoneEnabled != zoneEnabled)
|
||||
{
|
||||
d_ptr->zoneEnabled = zoneEnabled;
|
||||
Q_EMIT ZoneEnabledChanged(d_ptr->zoneEnabled);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
qWarning() << "property not handle: " << propName;
|
||||
return;
|
||||
}
|
||||
|
||||
bool __wm::compositingAllowSwitch()
|
||||
{
|
||||
return qvariant_cast<bool>(internalPropGet("compositingAllowSwitch", &d_ptr->compositingAllowSwitch));
|
||||
}
|
||||
|
||||
bool __wm::compositingEnabled()
|
||||
{
|
||||
return qvariant_cast<bool>(internalPropGet("compositingEnabled", &d_ptr->compositingEnabled));
|
||||
}
|
||||
|
||||
void __wm::setCompositingEnabled(bool value)
|
||||
{
|
||||
|
||||
internalPropSet("compositingEnabled", QVariant::fromValue(value), &d_ptr->compositingEnabled);
|
||||
}
|
||||
|
||||
bool __wm::compositingPossible()
|
||||
{
|
||||
return qvariant_cast<bool>(internalPropGet("compositingPossible", &d_ptr->compositingPossible));
|
||||
}
|
||||
|
||||
int __wm::cursorSize()
|
||||
{
|
||||
return qvariant_cast<int>(internalPropGet("cursorSize", &d_ptr->cursorSize));
|
||||
}
|
||||
|
||||
void __wm::setCursorSize(int value)
|
||||
{
|
||||
|
||||
internalPropSet("cursorSize", QVariant::fromValue(value), &d_ptr->cursorSize);
|
||||
}
|
||||
|
||||
QString __wm::cursorTheme()
|
||||
{
|
||||
return qvariant_cast<QString>(internalPropGet("cursorTheme", &d_ptr->cursorTheme));
|
||||
}
|
||||
|
||||
void __wm::setCursorTheme(const QString &value)
|
||||
{
|
||||
|
||||
internalPropSet("cursorTheme", QVariant::fromValue(value), &d_ptr->cursorTheme);
|
||||
}
|
||||
|
||||
bool __wm::zoneEnabled()
|
||||
{
|
||||
return qvariant_cast<bool>(internalPropGet("zoneEnabled", &d_ptr->zoneEnabled));
|
||||
}
|
||||
|
||||
void __wm::setZoneEnabled(bool value)
|
||||
{
|
||||
|
||||
internalPropSet("zoneEnabled", QVariant::fromValue(value), &d_ptr->zoneEnabled);
|
||||
}
|
||||
|
||||
void __wm::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &__wm::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void __wm::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
if (callName.isEmpty())
|
||||
return;
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
708
src/frameworkdbus/dbuswm.h
Normal file
708
src/frameworkdbus/dbuswm.h
Normal file
@ -0,0 +1,708 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c wm -p generated/com_deepin_wm ../xml/com.deepin.wm.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef COM_DEEPIN_WM_H
|
||||
#define COM_DEEPIN_WM_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
|
||||
/*
|
||||
* Proxy class for interface com.deepin.wm
|
||||
*/
|
||||
class __wmPrivate;
|
||||
class __wm : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "com.deepin.wm"; }
|
||||
|
||||
public:
|
||||
explicit __wm(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~__wm();
|
||||
|
||||
Q_PROPERTY(bool compositingAllowSwitch READ compositingAllowSwitch NOTIFY CompositingAllowSwitchChanged)
|
||||
bool compositingAllowSwitch();
|
||||
|
||||
Q_PROPERTY(bool compositingEnabled READ compositingEnabled WRITE setCompositingEnabled NOTIFY CompositingEnabledChanged)
|
||||
bool compositingEnabled();
|
||||
void setCompositingEnabled(bool value);
|
||||
|
||||
Q_PROPERTY(bool compositingPossible READ compositingPossible NOTIFY CompositingPossibleChanged)
|
||||
bool compositingPossible();
|
||||
|
||||
Q_PROPERTY(int cursorSize READ cursorSize WRITE setCursorSize NOTIFY CursorSizeChanged)
|
||||
int cursorSize();
|
||||
void setCursorSize(int value);
|
||||
|
||||
Q_PROPERTY(QString cursorTheme READ cursorTheme WRITE setCursorTheme NOTIFY CursorThemeChanged)
|
||||
QString cursorTheme();
|
||||
void setCursorTheme(const QString &value);
|
||||
|
||||
Q_PROPERTY(bool zoneEnabled READ zoneEnabled WRITE setZoneEnabled NOTIFY ZoneEnabledChanged)
|
||||
bool zoneEnabled();
|
||||
void setZoneEnabled(bool value);
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> BeginToMoveActiveWindow()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("BeginToMoveActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
inline void BeginToMoveActiveWindowQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("BeginToMoveActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> CancelPreviewWindow()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("CancelPreviewWindow"), argumentList);
|
||||
}
|
||||
|
||||
inline void CancelPreviewWindowQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("CancelPreviewWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> ChangeCurrentWorkspaceBackground(const QString &uri)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uri);
|
||||
return asyncCallWithArgumentList(QStringLiteral("ChangeCurrentWorkspaceBackground"), argumentList);
|
||||
}
|
||||
|
||||
inline void ChangeCurrentWorkspaceBackgroundQueued(const QString &uri)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uri);
|
||||
|
||||
CallQueued(QStringLiteral("ChangeCurrentWorkspaceBackground"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> ClearMoveStatus()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ClearMoveStatus"), argumentList);
|
||||
}
|
||||
|
||||
inline void ClearMoveStatusQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("ClearMoveStatus"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> EnableZoneDetected(bool enabled)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(enabled);
|
||||
return asyncCallWithArgumentList(QStringLiteral("EnableZoneDetected"), argumentList);
|
||||
}
|
||||
|
||||
inline void EnableZoneDetectedQueued(bool enabled)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(enabled);
|
||||
|
||||
CallQueued(QStringLiteral("EnableZoneDetected"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> GetAccel(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetAccel"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> GetAllAccels()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetAllAccels"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> GetCurrentDesktopStatus()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetCurrentDesktopStatus"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<int> GetCurrentWorkspace()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetCurrentWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> GetCurrentWorkspaceBackground()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetCurrentWorkspaceBackground"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> GetCurrentWorkspaceBackgroundForMonitor(const QString &strMonitorName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(strMonitorName);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetCurrentWorkspaceBackgroundForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QStringList> GetDefaultAccel(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetDefaultAccel"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> GetIsShowDesktop()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetIsShowDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> GetMultiTaskingStatus()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetMultiTaskingStatus"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<double> GetTouchBorderInterval()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetTouchBorderInterval"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> GetWorkspaceBackground(int index)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(index);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetWorkspaceBackground"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> GetWorkspaceBackgroundForMonitor(int index, const QString &strMonitorName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(index) << QVariant::fromValue(strMonitorName);
|
||||
return asyncCallWithArgumentList(QStringLiteral("GetWorkspaceBackgroundForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> MinimizeActiveWindow()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("MinimizeActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
inline void MinimizeActiveWindowQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("MinimizeActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> NextWorkspace()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("NextWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
inline void NextWorkspaceQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("NextWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> PerformAction(int type)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(type);
|
||||
return asyncCallWithArgumentList(QStringLiteral("PerformAction"), argumentList);
|
||||
}
|
||||
|
||||
inline void PerformActionQueued(int type)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(type);
|
||||
|
||||
CallQueued(QStringLiteral("PerformAction"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> PresentWindows(const QList<uint> &xids)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(xids);
|
||||
return asyncCallWithArgumentList(QStringLiteral("PresentWindows"), argumentList);
|
||||
}
|
||||
|
||||
inline void PresentWindowsQueued(const QList<uint> &xids)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(xids);
|
||||
|
||||
CallQueued(QStringLiteral("PresentWindows"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> PreviewWindow(uint xid)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(xid);
|
||||
return asyncCallWithArgumentList(QStringLiteral("PreviewWindow"), argumentList);
|
||||
}
|
||||
|
||||
inline void PreviewWindowQueued(uint xid)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(xid);
|
||||
|
||||
CallQueued(QStringLiteral("PreviewWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> PreviousWorkspace()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("PreviousWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
inline void PreviousWorkspaceQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("PreviousWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RemoveAccel(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
return asyncCallWithArgumentList(QStringLiteral("RemoveAccel"), argumentList);
|
||||
}
|
||||
|
||||
inline void RemoveAccelQueued(const QString &id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(id);
|
||||
|
||||
CallQueued(QStringLiteral("RemoveAccel"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<bool> SetAccel(const QString &data)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(data);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetAccel"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetCurrentWorkspace(int index)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(index);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetCurrentWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetCurrentWorkspaceQueued(int index)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(index);
|
||||
|
||||
CallQueued(QStringLiteral("SetCurrentWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetCurrentWorkspaceBackground(const QString &uri)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uri);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetCurrentWorkspaceBackground"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetCurrentWorkspaceBackgroundQueued(const QString &uri)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uri);
|
||||
|
||||
CallQueued(QStringLiteral("SetCurrentWorkspaceBackground"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetCurrentWorkspaceBackgroundForMonitor(const QString &uri, const QString &strMonitorName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uri) << QVariant::fromValue(strMonitorName);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetCurrentWorkspaceBackgroundForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetCurrentWorkspaceBackgroundForMonitorQueued(const QString &uri, const QString &strMonitorName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uri) << QVariant::fromValue(strMonitorName);
|
||||
|
||||
CallQueued(QStringLiteral("SetCurrentWorkspaceBackgroundForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetDecorationDeepinTheme(const QString &deepinThemeName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(deepinThemeName);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetDecorationDeepinTheme"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetDecorationDeepinThemeQueued(const QString &deepinThemeName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(deepinThemeName);
|
||||
|
||||
CallQueued(QStringLiteral("SetDecorationDeepinTheme"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetDecorationTheme(const QString &themeType, const QString &themeName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(themeType) << QVariant::fromValue(themeName);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetDecorationTheme"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetDecorationThemeQueued(const QString &themeType, const QString &themeName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(themeType) << QVariant::fromValue(themeName);
|
||||
|
||||
CallQueued(QStringLiteral("SetDecorationTheme"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetMultiTaskingStatus(bool isActive)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(isActive);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetMultiTaskingStatus"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetMultiTaskingStatusQueued(bool isActive)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(isActive);
|
||||
|
||||
CallQueued(QStringLiteral("SetMultiTaskingStatus"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetShowDesktop(bool isShowDesktop)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(isShowDesktop);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetShowDesktop"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetShowDesktopQueued(bool isShowDesktop)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(isShowDesktop);
|
||||
|
||||
CallQueued(QStringLiteral("SetShowDesktop"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetTouchBorderInterval(double interval)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(interval);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetTouchBorderInterval"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetTouchBorderIntervalQueued(double interval)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(interval);
|
||||
|
||||
CallQueued(QStringLiteral("SetTouchBorderInterval"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetTransientBackground(const QString &in0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(in0);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetTransientBackground"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetTransientBackgroundQueued(const QString &in0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(in0);
|
||||
|
||||
CallQueued(QStringLiteral("SetTransientBackground"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetTransientBackgroundForMonitor(const QString &uri, const QString &strMonitorName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uri) << QVariant::fromValue(strMonitorName);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetTransientBackgroundForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetTransientBackgroundForMonitorQueued(const QString &uri, const QString &strMonitorName)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(uri) << QVariant::fromValue(strMonitorName);
|
||||
|
||||
CallQueued(QStringLiteral("SetTransientBackgroundForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetWorkspaceBackground(int index, const QString &uri)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(index) << QVariant::fromValue(uri);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetWorkspaceBackground"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetWorkspaceBackgroundQueued(int index, const QString &uri)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(index) << QVariant::fromValue(uri);
|
||||
|
||||
CallQueued(QStringLiteral("SetWorkspaceBackground"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SetWorkspaceBackgroundForMonitor(int index, const QString &strMonitorName, const QString &uri)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(index) << QVariant::fromValue(strMonitorName) << QVariant::fromValue(uri);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetWorkspaceBackgroundForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
inline void SetWorkspaceBackgroundForMonitorQueued(int index, const QString &strMonitorName, const QString &uri)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(index) << QVariant::fromValue(strMonitorName) << QVariant::fromValue(uri);
|
||||
|
||||
CallQueued(QStringLiteral("SetWorkspaceBackgroundForMonitor"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> ShowAllWindow()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ShowAllWindow"), argumentList);
|
||||
}
|
||||
|
||||
inline void ShowAllWindowQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("ShowAllWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> ShowWindow()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ShowWindow"), argumentList);
|
||||
}
|
||||
|
||||
inline void ShowWindowQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("ShowWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> ShowWorkspace()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ShowWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
inline void ShowWorkspaceQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("ShowWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SwitchApplication(bool backward)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(backward);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SwitchApplication"), argumentList);
|
||||
}
|
||||
|
||||
inline void SwitchApplicationQueued(bool backward)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(backward);
|
||||
|
||||
CallQueued(QStringLiteral("SwitchApplication"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> SwitchToWorkspace(bool backward)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(backward);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SwitchToWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
inline void SwitchToWorkspaceQueued(bool backward)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(backward);
|
||||
|
||||
CallQueued(QStringLiteral("SwitchToWorkspace"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> TileActiveWindow(uint side)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(side);
|
||||
return asyncCallWithArgumentList(QStringLiteral("TileActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
inline void TileActiveWindowQueued(uint side)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(side);
|
||||
|
||||
CallQueued(QStringLiteral("TileActiveWindow"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> ToggleActiveWindowMaximize()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("ToggleActiveWindowMaximize"), argumentList);
|
||||
}
|
||||
|
||||
inline void ToggleActiveWindowMaximizeQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("ToggleActiveWindowMaximize"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> TouchToMove(int x, int y)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y);
|
||||
return asyncCallWithArgumentList(QStringLiteral("TouchToMove"), argumentList);
|
||||
}
|
||||
|
||||
inline void TouchToMoveQueued(int x, int y)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y);
|
||||
|
||||
CallQueued(QStringLiteral("TouchToMove"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<int> WorkspaceCount()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("WorkspaceCount"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void WorkspaceBackgroundChanged(int index, const QString &newUri);
|
||||
void WorkspaceBackgroundChangedForMonitor(int index, const QString &strMonitorName, const QString &uri);
|
||||
void WorkspaceSwitched(int from, int to);
|
||||
void compositingEnabledChanged(bool enabled);
|
||||
void wmCompositingEnabledChanged(bool enabled);
|
||||
void workspaceCountChanged(int count);
|
||||
// begin property changed signals
|
||||
void CompositingAllowSwitchChanged(bool value) const;
|
||||
void CompositingEnabledChanged(bool value) const;
|
||||
void CompositingPossibleChanged(bool value) const;
|
||||
void CursorSizeChanged(int value) const;
|
||||
void CursorThemeChanged(const QString & value) const;
|
||||
void ZoneEnabledChanged(bool value) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
void onPropertyChanged(const QString &propName, const QVariant &value);
|
||||
|
||||
private:
|
||||
__wmPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace com {
|
||||
namespace deepin {
|
||||
typedef ::__wm WM;
|
||||
}
|
||||
}
|
||||
#endif
|
71
src/frameworkdbus/dbuswmswitcher.cpp
Normal file
71
src/frameworkdbus/dbuswmswitcher.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c WMSwitcher -p generated/com_deepin_wmswitcher ../xml/com.deepin.WMSwitcher.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "dbuswmswitcher.h"
|
||||
|
||||
/*
|
||||
* Implementation of interface class __WMSwitcher
|
||||
*/
|
||||
|
||||
class __WMSwitcherPrivate
|
||||
{
|
||||
public:
|
||||
__WMSwitcherPrivate() = default;
|
||||
|
||||
// begin member variables
|
||||
|
||||
public:
|
||||
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
|
||||
QMap<QString, QList<QVariant>> m_waittingCalls;
|
||||
};
|
||||
|
||||
__WMSwitcher::__WMSwitcher(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: DBusExtendedAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
, d_ptr(new __WMSwitcherPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
__WMSwitcher::~__WMSwitcher()
|
||||
{
|
||||
qDeleteAll(d_ptr->m_processingCalls.values());
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void __WMSwitcher::CallQueued(const QString &callName, const QList<QVariant> &args)
|
||||
{
|
||||
if (d_ptr->m_waittingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls[callName] = args;
|
||||
return;
|
||||
}
|
||||
if (d_ptr->m_processingCalls.contains(callName))
|
||||
{
|
||||
d_ptr->m_waittingCalls.insert(callName, args);
|
||||
} else {
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCallWithArgumentList(callName, args));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &__WMSwitcher::onPendingCallFinished);
|
||||
d_ptr->m_processingCalls.insert(callName, watcher);
|
||||
}
|
||||
}
|
||||
|
||||
void __WMSwitcher::onPendingCallFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
w->deleteLater();
|
||||
const auto callName = d_ptr->m_processingCalls.key(w);
|
||||
Q_ASSERT(!callName.isEmpty());
|
||||
if (callName.isEmpty())
|
||||
return;
|
||||
d_ptr->m_processingCalls.remove(callName);
|
||||
if (!d_ptr->m_waittingCalls.contains(callName))
|
||||
return;
|
||||
const auto args = d_ptr->m_waittingCalls.take(callName);
|
||||
CallQueued(callName, args);
|
||||
}
|
122
src/frameworkdbus/dbuswmswitcher.h
Normal file
122
src/frameworkdbus/dbuswmswitcher.h
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp-fix version 0.8
|
||||
* Command line was: qdbusxml2cpp-fix -c WMSwitcher -p generated/com_deepin_wmswitcher ../xml/com.deepin.WMSwitcher.xml
|
||||
*
|
||||
* qdbusxml2cpp-fix is Copyright (C) 2016 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef COM_DEEPIN_WMSWITCHER_H
|
||||
#define COM_DEEPIN_WMSWITCHER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
|
||||
/*
|
||||
* Proxy class for interface com.deepin.WMSwitcher
|
||||
*/
|
||||
class __WMSwitcherPrivate;
|
||||
class __WMSwitcher : public DBusExtendedAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "com.deepin.WMSwitcher"; }
|
||||
|
||||
public:
|
||||
explicit __WMSwitcher(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
~__WMSwitcher();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<bool> AllowSwitch()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("AllowSwitch"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<QString> CurrentWM()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("CurrentWM"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RequestSwitchWM()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RequestSwitchWM"), argumentList);
|
||||
}
|
||||
|
||||
inline void RequestSwitchWMQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RequestSwitchWM"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> RestartWM()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("RestartWM"), argumentList);
|
||||
}
|
||||
|
||||
inline void RestartWMQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("RestartWM"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
inline QDBusPendingReply<> Start2DWM()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Start2DWM"), argumentList);
|
||||
}
|
||||
|
||||
inline void Start2DWMQueued()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
||||
CallQueued(QStringLiteral("Start2DWM"), argumentList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void WMChanged(const QString &in0);
|
||||
// begin property changed signals
|
||||
|
||||
public Q_SLOTS:
|
||||
void CallQueued(const QString &callName, const QList<QVariant> &args);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPendingCallFinished(QDBusPendingCallWatcher *w);
|
||||
|
||||
private:
|
||||
__WMSwitcherPrivate *d_ptr;
|
||||
};
|
||||
|
||||
namespace com {
|
||||
namespace deepin {
|
||||
typedef ::__WMSwitcher WMSwitcher;
|
||||
}
|
||||
}
|
||||
#endif
|
1
src/frameworkdbus/qtdbusextended/DBusExtended
Normal file
1
src/frameworkdbus/qtdbusextended/DBusExtended
Normal file
@ -0,0 +1 @@
|
||||
#include "dbusextended.h"
|
@ -0,0 +1 @@
|
||||
#include "dbusextendedabstractinterface.h"
|
35
src/frameworkdbus/qtdbusextended/dbusextended.h
Normal file
35
src/frameworkdbus/qtdbusextended/dbusextended.h
Normal file
@ -0,0 +1,35 @@
|
||||
// -*- c++ -*-
|
||||
|
||||
/*!
|
||||
*
|
||||
* Copyright (C) 2015 Jolla Ltd.
|
||||
*
|
||||
* Contact: Valerio Valerio <valerio.valerio@jolla.com>
|
||||
* Author: Andres Gomez <andres.gomez@jolla.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef QT_DBUS_EXTENDED_H
|
||||
#define QT_DBUS_EXTENDED_H
|
||||
|
||||
#if defined(QT_DBUS_EXTENDED_LIBRARY)
|
||||
# define QT_DBUS_EXTENDED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define QT_DBUS_EXTENDED_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif /* QT_DBUS_EXTENDED_H */
|
@ -0,0 +1,525 @@
|
||||
// -*- c++ -*-
|
||||
|
||||
/*!
|
||||
*
|
||||
* Copyright (C) 2015 Jolla Ltd.
|
||||
*
|
||||
* Contact: Valerio Valerio <valerio.valerio@jolla.com>
|
||||
* Author: Andres Gomez <andres.gomez@jolla.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "dbusextendedpendingcallwatcher_p.h"
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
|
||||
#include <QtDBus/QDBusMetaType>
|
||||
#include <QtDBus/QDBusMessage>
|
||||
#include <QtDBus/QDBusPendingCall>
|
||||
#include <QtDBus/QDBusPendingCallWatcher>
|
||||
#include <QtDBus/QDBusPendingReply>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QMetaProperty>
|
||||
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, dBusInterface, ("org.freedesktop.DBus"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, dBusPropertiesInterface, ("org.freedesktop.DBus.Properties"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, dBusPropertiesChangedSignal, ("PropertiesChanged"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, propertyChangedSignature, ("propertyChanged(QString,QVariant)"))
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, propertyInvalidatedSignature, ("propertyInvalidated(QString)"))
|
||||
|
||||
|
||||
DBusExtendedAbstractInterface::DBusExtendedAbstractInterface(const QString &service, const QString &path, const char *interface, const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, interface, connection, parent)
|
||||
, m_sync(true)
|
||||
, m_useCache(false)
|
||||
, m_getAllPendingCallWatcher(0)
|
||||
, m_propertiesChangedConnected(false)
|
||||
{
|
||||
const_cast<QDBusConnection&>(connection).connect(QString("org.freedesktop.DBus"), QString("/org/freedesktop/DBus"), QString("org.freedesktop.DBus"), QString("NameOwnerChanged"), this, SLOT(onDBusNameOwnerChanged(QString,QString,QString)));
|
||||
}
|
||||
|
||||
DBusExtendedAbstractInterface::~DBusExtendedAbstractInterface()
|
||||
{
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::setSync(bool sync) { setSync(sync, true); }
|
||||
|
||||
/*
|
||||
* Note: After sync is set to false, it will always return a empty value
|
||||
* if you call the property's get function directly. So you can only get it
|
||||
* through the changed signal when you get an property, and it's also a good idea
|
||||
* to save a cache yourself.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 注意: 如果设置 sync 为 false 那么在调用属性的 get 函数获取一个属性时会一直返回空值,
|
||||
* 解决方法是监听属性的 changed 信号并自行保存一份缓存, 让 changed 信号修改这个缓存
|
||||
*/
|
||||
void DBusExtendedAbstractInterface::setSync(bool sync, bool autoStart)
|
||||
{
|
||||
m_sync = sync;
|
||||
|
||||
// init all properties
|
||||
if (autoStart && !m_sync && !isValid())
|
||||
startServiceProcess();
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::getAllProperties()
|
||||
{
|
||||
m_lastExtendedError = QDBusError();
|
||||
|
||||
if (!isValid()) {
|
||||
QString errorMessage = QStringLiteral("This Extended DBus interface is not valid yet.");
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qDebug() << Q_FUNC_INFO << errorMessage;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_sync && m_getAllPendingCallWatcher) {
|
||||
// Call already in place, not repeating ...
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), *dBusPropertiesInterface(), QStringLiteral("GetAll"));
|
||||
msg << interface();
|
||||
|
||||
if (m_sync) {
|
||||
QDBusMessage reply = connection().call(msg);
|
||||
|
||||
if (reply.type() != QDBusMessage::ReplyMessage) {
|
||||
m_lastExtendedError = QDBusError(reply);
|
||||
qWarning() << Q_FUNC_INFO << m_lastExtendedError.message();
|
||||
return;
|
||||
}
|
||||
|
||||
if (reply.signature() != QLatin1String("a{sv}")) {
|
||||
QString errorMessage = QStringLiteral("Invalid signature \"%1\" in return from call to %2")
|
||||
.arg(reply.signature(),
|
||||
QString(*dBusPropertiesInterface()));
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
m_lastExtendedError = QDBusError(QDBusError::InvalidSignature, errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap value = reply.arguments().at(0).toMap();
|
||||
onPropertiesChanged(interface(), value, QStringList());
|
||||
} else {
|
||||
QDBusPendingReply<QVariantMap> async = connection().asyncCall(msg);
|
||||
m_getAllPendingCallWatcher = new QDBusPendingCallWatcher(async, this);
|
||||
|
||||
connect(m_getAllPendingCallWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(onAsyncGetAllPropertiesFinished(QDBusPendingCallWatcher*)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::connectNotify(const QMetaMethod &signal)
|
||||
{
|
||||
if (signal.methodType() == QMetaMethod::Signal
|
||||
&& (signal.methodSignature() == *propertyChangedSignature()
|
||||
|| signal.methodSignature() == *propertyInvalidatedSignature())) {
|
||||
if (!m_propertiesChangedConnected) {
|
||||
QStringList argumentMatch;
|
||||
argumentMatch << interface();
|
||||
connection().connect(service(), path(), *dBusPropertiesInterface(), *dBusPropertiesChangedSignal(),
|
||||
argumentMatch, QString(),
|
||||
this, SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
|
||||
|
||||
m_propertiesChangedConnected = true;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
QDBusAbstractInterface::connectNotify(signal);
|
||||
}
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::disconnectNotify(const QMetaMethod &signal)
|
||||
{
|
||||
if (signal.methodType() == QMetaMethod::Signal
|
||||
&& (signal.methodSignature() == *propertyChangedSignature()
|
||||
|| signal.methodSignature() == *propertyInvalidatedSignature())) {
|
||||
if (m_propertiesChangedConnected
|
||||
&& 0 == receivers(propertyChangedSignature()->constData())
|
||||
&& 0 == receivers(propertyInvalidatedSignature()->constData())) {
|
||||
QStringList argumentMatch;
|
||||
argumentMatch << interface();
|
||||
connection().disconnect(service(), path(), *dBusPropertiesInterface(), *dBusPropertiesChangedSignal(),
|
||||
argumentMatch, QString(),
|
||||
this, SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
|
||||
|
||||
m_propertiesChangedConnected = false;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
QDBusAbstractInterface::disconnectNotify(signal);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant DBusExtendedAbstractInterface::internalPropGet(const char *propname, void *propertyPtr)
|
||||
{
|
||||
m_lastExtendedError = QDBusError();
|
||||
|
||||
if (m_useCache) {
|
||||
int propertyIndex = metaObject()->indexOfProperty(propname);
|
||||
QMetaProperty metaProperty = metaObject()->property(propertyIndex);
|
||||
return QVariant(metaProperty.userType(), propertyPtr);
|
||||
}
|
||||
|
||||
if (m_sync) {
|
||||
QVariant ret = property(propname);
|
||||
|
||||
QMetaType::construct(ret.userType(), propertyPtr, ret.constData());
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
if (!isValid()) {
|
||||
QString errorMessage = QStringLiteral("This Extended DBus interface is not valid yet.");
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qDebug() << Q_FUNC_INFO << errorMessage;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int propertyIndex = metaObject()->indexOfProperty(propname);
|
||||
|
||||
if (-1 == propertyIndex) {
|
||||
QString errorMessage = QStringLiteral("Got unknown property \"%1\" to read")
|
||||
.arg(QString::fromLatin1(propname));
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QMetaProperty metaProperty = metaObject()->property(propertyIndex);
|
||||
|
||||
if (!metaProperty.isReadable()) {
|
||||
QString errorMessage = QStringLiteral("Property \"%1\" is NOT readable")
|
||||
.arg(QString::fromLatin1(propname));
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// is this metatype registered?
|
||||
const char *expectedSignature = "";
|
||||
if (int(metaProperty.type()) != QMetaType::QVariant) {
|
||||
expectedSignature = QDBusMetaType::typeToSignature(metaProperty.userType());
|
||||
if (0 == expectedSignature) {
|
||||
QString errorMessage =
|
||||
QStringLiteral("Type %1 must be registered with Qt D-Bus "
|
||||
"before it can be used to read property "
|
||||
"%2.%3")
|
||||
.arg(metaProperty.typeName(),
|
||||
interface(),
|
||||
propname);
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
asyncProperty(propname);
|
||||
return QVariant(metaProperty.userType(), propertyPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::internalPropSet(const char *propname, const QVariant &value, void *propertyPtr)
|
||||
{
|
||||
m_lastExtendedError = QDBusError();
|
||||
|
||||
if (m_sync) {
|
||||
setProperty(propname, value);
|
||||
} else {
|
||||
if (!isValid()) {
|
||||
QString errorMessage = QStringLiteral("This interface is not yet valid");
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qDebug() << Q_FUNC_INFO << errorMessage;
|
||||
return;
|
||||
}
|
||||
|
||||
int propertyIndex = metaObject()->indexOfProperty(propname);
|
||||
|
||||
if (-1 == propertyIndex) {
|
||||
QString errorMessage = QStringLiteral("Got unknown property \"%1\" to write")
|
||||
.arg(QString::fromLatin1(propname));
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return;
|
||||
}
|
||||
|
||||
QMetaProperty metaProperty = metaObject()->property(propertyIndex);
|
||||
|
||||
if (!metaProperty.isWritable()) {
|
||||
QString errorMessage = QStringLiteral("Property \"%1\" is NOT writable")
|
||||
.arg(QString::fromLatin1(propname));
|
||||
m_lastExtendedError = QDBusMessage::createError(QDBusError::Failed, errorMessage);
|
||||
qWarning() << Q_FUNC_INFO << errorMessage;
|
||||
return;
|
||||
}
|
||||
|
||||
QVariant variant = QVariant(metaProperty.type(), propertyPtr);
|
||||
variant = value;
|
||||
|
||||
asyncSetProperty(propname, variant);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant DBusExtendedAbstractInterface::asyncProperty(const QString &propertyName)
|
||||
{
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), *dBusPropertiesInterface(), QStringLiteral("Get"));
|
||||
msg << interface() << propertyName;
|
||||
QDBusPendingReply<QVariant> async = connection().asyncCall(msg);
|
||||
DBusExtendedPendingCallWatcher *watcher = new DBusExtendedPendingCallWatcher(async, propertyName, QVariant(), this);
|
||||
|
||||
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(onAsyncPropertyFinished(QDBusPendingCallWatcher*)));
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::asyncSetProperty(const QString &propertyName, const QVariant &value)
|
||||
{
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), *dBusPropertiesInterface(), QStringLiteral("Set"));
|
||||
|
||||
msg << interface() << propertyName << QVariant::fromValue(QDBusVariant(value));
|
||||
QDBusPendingReply<> async = connection().asyncCall(msg);
|
||||
DBusExtendedPendingCallWatcher *watcher = new DBusExtendedPendingCallWatcher(async, propertyName, value, this);
|
||||
|
||||
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(onAsyncSetPropertyFinished(QDBusPendingCallWatcher*)));
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::startServiceProcess()
|
||||
{
|
||||
const QString &servName = service();
|
||||
|
||||
if (isValid())
|
||||
{
|
||||
qWarning() << "Service" << servName << "is already started.";
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/", *dBusInterface(), QStringLiteral("StartServiceByName"));
|
||||
msg << servName << quint32(0);
|
||||
QDBusPendingReply<quint32> async = connection().asyncCall(msg);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this);
|
||||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, &DBusExtendedAbstractInterface::onStartServiceProcessFinished);
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::onStartServiceProcessFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
if (w->isError())
|
||||
{
|
||||
m_lastExtendedError = w->error();
|
||||
} else {
|
||||
m_lastExtendedError = QDBusError();
|
||||
}
|
||||
|
||||
QDBusPendingReply<quint32> reply = *w;
|
||||
|
||||
Q_EMIT serviceStartFinished(reply.value());
|
||||
|
||||
w->deleteLater();
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::onAsyncPropertyFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
DBusExtendedPendingCallWatcher *watcher = qobject_cast<DBusExtendedPendingCallWatcher *>(w);
|
||||
Q_ASSERT(watcher);
|
||||
|
||||
QDBusPendingReply<QVariant> reply = *watcher;
|
||||
|
||||
if (reply.isError()) {
|
||||
m_lastExtendedError = reply.error();
|
||||
} else {
|
||||
int propertyIndex = metaObject()->indexOfProperty(watcher->asyncProperty().toLatin1().constData());
|
||||
QVariant value = demarshall(interface(),
|
||||
metaObject()->property(propertyIndex),
|
||||
reply.value(),
|
||||
&m_lastExtendedError);
|
||||
|
||||
if (m_lastExtendedError.isValid()) {
|
||||
Q_EMIT propertyInvalidated(watcher->asyncProperty());
|
||||
} else {
|
||||
Q_EMIT propertyChanged(watcher->asyncProperty(), value);
|
||||
}
|
||||
}
|
||||
|
||||
Q_EMIT asyncPropertyFinished(watcher->asyncProperty());
|
||||
watcher->deleteLater();
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::onAsyncSetPropertyFinished(QDBusPendingCallWatcher *w)
|
||||
{
|
||||
DBusExtendedPendingCallWatcher *watcher = qobject_cast<DBusExtendedPendingCallWatcher *>(w);
|
||||
Q_ASSERT(watcher);
|
||||
|
||||
QDBusPendingReply<> reply = *watcher;
|
||||
|
||||
if (reply.isError()) {
|
||||
m_lastExtendedError = reply.error();
|
||||
} else {
|
||||
m_lastExtendedError = QDBusError();
|
||||
}
|
||||
|
||||
Q_EMIT asyncSetPropertyFinished(watcher->asyncProperty());
|
||||
|
||||
// Resetting the property to its previous value after sending the
|
||||
// finished signal
|
||||
if (reply.isError()) {
|
||||
m_lastExtendedError = QDBusError();
|
||||
Q_EMIT propertyChanged(watcher->asyncProperty(), watcher->previousValue());
|
||||
}
|
||||
|
||||
watcher->deleteLater();
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::onAsyncGetAllPropertiesFinished(QDBusPendingCallWatcher *watcher)
|
||||
{
|
||||
m_getAllPendingCallWatcher = 0;
|
||||
|
||||
QDBusPendingReply<QVariantMap> reply = *watcher;
|
||||
|
||||
if (reply.isError()) {
|
||||
m_lastExtendedError = reply.error();
|
||||
} else {
|
||||
m_lastExtendedError = QDBusError();
|
||||
}
|
||||
|
||||
Q_EMIT asyncGetAllPropertiesFinished();
|
||||
|
||||
if (!reply.isError()) {
|
||||
onPropertiesChanged(interface(), reply.value(), QStringList());
|
||||
}
|
||||
|
||||
watcher->deleteLater();
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::onPropertiesChanged(const QString& interfaceName,
|
||||
const QVariantMap& changedProperties,
|
||||
const QStringList& invalidatedProperties)
|
||||
{
|
||||
if (interfaceName == interface()) {
|
||||
QVariantMap::const_iterator i = changedProperties.constBegin();
|
||||
while (i != changedProperties.constEnd()) {
|
||||
int propertyIndex = metaObject()->indexOfProperty(i.key().toLatin1().constData());
|
||||
|
||||
if (-1 == propertyIndex) {
|
||||
qDebug() << Q_FUNC_INFO << "Got unknown changed property" << i.key();
|
||||
} else {
|
||||
QVariant value = demarshall(interface(), metaObject()->property(propertyIndex), i.value(), &m_lastExtendedError);
|
||||
|
||||
if (m_lastExtendedError.isValid()) {
|
||||
Q_EMIT propertyInvalidated(i.key());
|
||||
} else {
|
||||
Q_EMIT propertyChanged(i.key(), value);
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
QStringList::const_iterator j = invalidatedProperties.constBegin();
|
||||
while (j != invalidatedProperties.constEnd()) {
|
||||
if (-1 == metaObject()->indexOfProperty(j->toLatin1().constData())) {
|
||||
qDebug() << Q_FUNC_INFO << "Got unknown invalidated property" << *j;
|
||||
} else {
|
||||
m_lastExtendedError = QDBusError();
|
||||
Q_EMIT propertyInvalidated(*j);
|
||||
}
|
||||
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DBusExtendedAbstractInterface::onDBusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
|
||||
{
|
||||
if (name == service() && oldOwner.isEmpty())
|
||||
{
|
||||
m_dbusOwner = newOwner;
|
||||
Q_EMIT serviceValidChanged(true);
|
||||
}
|
||||
else if (name == m_dbusOwner && newOwner.isEmpty())
|
||||
{
|
||||
m_dbusOwner.clear();
|
||||
Q_EMIT serviceValidChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant DBusExtendedAbstractInterface::demarshall(const QString &interface, const QMetaProperty &metaProperty, const QVariant &value, QDBusError *error)
|
||||
{
|
||||
Q_ASSERT(metaProperty.isValid());
|
||||
Q_ASSERT(error != 0);
|
||||
|
||||
if (value.userType() == metaProperty.userType()) {
|
||||
// No need demarshalling. Passing back straight away ...
|
||||
*error = QDBusError();
|
||||
return value;
|
||||
}
|
||||
|
||||
QVariant result = QVariant(metaProperty.userType(), (void*)0);
|
||||
QString errorMessage;
|
||||
const char *expectedSignature = QDBusMetaType::typeToSignature(metaProperty.userType());
|
||||
|
||||
if (value.userType() == qMetaTypeId<QDBusArgument>()) {
|
||||
// demarshalling a DBus argument ...
|
||||
QDBusArgument dbusArg = value.value<QDBusArgument>();
|
||||
|
||||
if (expectedSignature == dbusArg.currentSignature().toLatin1()) {
|
||||
QDBusMetaType::demarshall(dbusArg, metaProperty.userType(), result.data());
|
||||
if (!result.isValid()) {
|
||||
errorMessage = QStringLiteral("Unexpected failure demarshalling "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
expectedSignature);
|
||||
}
|
||||
} else {
|
||||
errorMessage = QStringLiteral("Unexpected `user type' (%2) "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(dbusArg.currentSignature(),
|
||||
interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
QString::fromLatin1(expectedSignature));
|
||||
}
|
||||
} else {
|
||||
const char *actualSignature = QDBusMetaType::typeToSignature(value.userType());
|
||||
|
||||
errorMessage = QStringLiteral("Unexpected `%1' (%2) "
|
||||
"upon PropertiesChanged signal arrival "
|
||||
"for property `%3.%4' (expected type `%5' (%6))")
|
||||
.arg(QString::fromLatin1(value.typeName()),
|
||||
QString::fromLatin1(actualSignature),
|
||||
interface,
|
||||
QString::fromLatin1(metaProperty.name()),
|
||||
QString::fromLatin1(metaProperty.typeName()),
|
||||
QString::fromLatin1(expectedSignature));
|
||||
}
|
||||
|
||||
if (errorMessage.isEmpty()) {
|
||||
*error = QDBusError();
|
||||
} else {
|
||||
*error = QDBusMessage::createError(QDBusError::InvalidSignature, errorMessage);
|
||||
qDebug() << Q_FUNC_INFO << errorMessage;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
103
src/frameworkdbus/qtdbusextended/dbusextendedabstractinterface.h
Normal file
103
src/frameworkdbus/qtdbusextended/dbusextendedabstractinterface.h
Normal file
@ -0,0 +1,103 @@
|
||||
// -*- c++ -*-
|
||||
|
||||
/*!
|
||||
*
|
||||
* Copyright (C) 2015 Jolla Ltd.
|
||||
*
|
||||
* Contact: Valerio Valerio <valerio.valerio@jolla.com>
|
||||
* Author: Andres Gomez <andres.gomez@jolla.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DBUSEXTENDEDABSTRACTINTERFACE_H
|
||||
#define DBUSEXTENDEDABSTRACTINTERFACE_H
|
||||
|
||||
#include <DBusExtended>
|
||||
|
||||
#include <QDBusAbstractInterface>
|
||||
#include <QDBusError>
|
||||
|
||||
class QDBusPendingCallWatcher;
|
||||
class DBusExtendedPendingCallWatcher;
|
||||
|
||||
class QT_DBUS_EXTENDED_EXPORT DBusExtendedAbstractInterface: public QDBusAbstractInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~DBusExtendedAbstractInterface();
|
||||
|
||||
Q_PROPERTY(bool sync READ sync WRITE setSync)
|
||||
inline bool sync() const { return m_sync; }
|
||||
void setSync(bool sync);
|
||||
void setSync(bool sync, bool autoStart);
|
||||
|
||||
Q_PROPERTY(bool useCache READ useCache WRITE setUseCache)
|
||||
inline bool useCache() const { return m_useCache; }
|
||||
inline void setUseCache(bool useCache) { m_useCache = useCache; }
|
||||
|
||||
void getAllProperties();
|
||||
inline QDBusError lastExtendedError() const { return m_lastExtendedError; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void startServiceProcess();
|
||||
|
||||
protected:
|
||||
DBusExtendedAbstractInterface(const QString &service,
|
||||
const QString &path,
|
||||
const char *interface,
|
||||
const QDBusConnection &connection,
|
||||
QObject *parent);
|
||||
|
||||
void connectNotify(const QMetaMethod &signal);
|
||||
void disconnectNotify(const QMetaMethod &signal);
|
||||
QVariant internalPropGet(const char *propname, void *propertyPtr);
|
||||
void internalPropSet(const char *propname, const QVariant &value, void *propertyPtr);
|
||||
|
||||
Q_SIGNALS:
|
||||
void serviceValidChanged(const bool valid) const;
|
||||
void serviceStartFinished(const quint32 ret) const;
|
||||
void propertyChanged(const QString &propertyName, const QVariant &value);
|
||||
void propertyInvalidated(const QString &propertyName);
|
||||
void asyncPropertyFinished(const QString &propertyName);
|
||||
void asyncSetPropertyFinished(const QString &propertyName);
|
||||
void asyncGetAllPropertiesFinished();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPropertiesChanged(const QString& interfaceName,
|
||||
const QVariantMap& changedProperties,
|
||||
const QStringList& invalidatedProperties);
|
||||
void onDBusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
|
||||
void onAsyncPropertyFinished(QDBusPendingCallWatcher *w);
|
||||
void onAsyncSetPropertyFinished(QDBusPendingCallWatcher *w);
|
||||
void onAsyncGetAllPropertiesFinished(QDBusPendingCallWatcher *watcher);
|
||||
void onStartServiceProcessFinished(QDBusPendingCallWatcher *w);
|
||||
|
||||
private:
|
||||
QVariant asyncProperty(const QString &propertyName);
|
||||
void asyncSetProperty(const QString &propertyName, const QVariant &value);
|
||||
static QVariant demarshall(const QString &interface, const QMetaProperty &metaProperty, const QVariant &value, QDBusError *error);
|
||||
|
||||
bool m_sync;
|
||||
bool m_useCache;
|
||||
QDBusPendingCallWatcher *m_getAllPendingCallWatcher;
|
||||
QDBusError m_lastExtendedError;
|
||||
QString m_dbusOwner;
|
||||
bool m_propertiesChangedConnected;
|
||||
};
|
||||
|
||||
#endif /* DBUSEXTENDEDABSTRACTINTERFACE_H */
|
@ -0,0 +1,38 @@
|
||||
// -*- c++ -*-
|
||||
|
||||
/*!
|
||||
*
|
||||
* Copyright (C) 2015 Jolla Ltd.
|
||||
*
|
||||
* Contact: Valerio Valerio <valerio.valerio@jolla.com>
|
||||
* Author: Andres Gomez <andres.gomez@jolla.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "dbusextendedpendingcallwatcher_p.h"
|
||||
|
||||
|
||||
DBusExtendedPendingCallWatcher::DBusExtendedPendingCallWatcher(const QDBusPendingCall &call, const QString &asyncProperty, const QVariant &previousValue, QObject *parent)
|
||||
: QDBusPendingCallWatcher(call, parent)
|
||||
, m_asyncProperty(asyncProperty)
|
||||
, m_previousValue(previousValue)
|
||||
{
|
||||
}
|
||||
|
||||
DBusExtendedPendingCallWatcher::~DBusExtendedPendingCallWatcher()
|
||||
{
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
// -*- c++ -*-
|
||||
|
||||
/*!
|
||||
*
|
||||
* Copyright (C) 2015 Jolla Ltd.
|
||||
*
|
||||
* Contact: Valerio Valerio <valerio.valerio@jolla.com>
|
||||
* Author: Andres Gomez <andres.gomez@jolla.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the public API. This header file may
|
||||
// change from version to version without notice, or even be
|
||||
// removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#ifndef DBUSEXTENDEDPENDINGCALLWATCHER_P_H
|
||||
#define DBUSEXTENDEDPENDINGCALLWATCHER_P_H
|
||||
|
||||
#include <QDBusPendingCallWatcher>
|
||||
#include <QDBusError>
|
||||
|
||||
class DBusExtendedPendingCallWatcher: public QDBusPendingCallWatcher
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DBusExtendedPendingCallWatcher(const QDBusPendingCall &call,
|
||||
const QString &asyncProperty,
|
||||
const QVariant &previousValue,
|
||||
QObject *parent = 0);
|
||||
~DBusExtendedPendingCallWatcher();
|
||||
|
||||
Q_PROPERTY(QString AsyncProperty READ asyncProperty)
|
||||
inline QString asyncProperty() const { return m_asyncProperty; }
|
||||
|
||||
Q_PROPERTY(QVariant PreviousValue READ previousValue)
|
||||
inline QVariant previousValue() const { return m_previousValue; }
|
||||
|
||||
private:
|
||||
QString m_asyncProperty;
|
||||
QVariant m_previousValue;
|
||||
};
|
||||
|
||||
#endif /* DBUSEXTENDEDPENDINGCALLWATCHER_P_H */
|
48
src/frameworkdbus/types/launcheriteminfo.cpp
Normal file
48
src/frameworkdbus/types/launcheriteminfo.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: LiLinling <lilinling_cm@deepin.com>
|
||||
*
|
||||
* Maintainer: LiLinling <lilinling_cm@deepin.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "launcheriteminfo.h"
|
||||
|
||||
bool LauncherItemInfo::operator!=(const LauncherItemInfo &itemInfo)
|
||||
{
|
||||
return itemInfo.ID != ID;
|
||||
}
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const LauncherItemInfo &itemInfo)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << itemInfo.Path << itemInfo.Name << itemInfo.ID << itemInfo.Icon << itemInfo.CategoryID << itemInfo.TimeInstalled;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, LauncherItemInfo &itemInfo)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument >> itemInfo.Path >> itemInfo.Name >> itemInfo.ID >> itemInfo.Icon >> itemInfo.CategoryID >> itemInfo.TimeInstalled;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
void registerLauncherItemInfoMetaType()
|
||||
{
|
||||
qRegisterMetaType<LauncherItemInfo>("ItemInfo");
|
||||
qDBusRegisterMetaType<LauncherItemInfo>();
|
||||
}
|
42
src/frameworkdbus/types/launcheriteminfo.h
Normal file
42
src/frameworkdbus/types/launcheriteminfo.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: LiLinling <lilinling_cm@deepin.com>
|
||||
*
|
||||
* Maintainer: LiLinling <lilinling_cm@deepin.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <QtCore/QList>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
struct LauncherItemInfo {
|
||||
QString Path;
|
||||
QString Name;
|
||||
QString ID;
|
||||
QString Icon;
|
||||
qint64 CategoryID;
|
||||
qint64 TimeInstalled;
|
||||
bool operator!=(const LauncherItemInfo &versionInfo);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(LauncherItemInfo)
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const LauncherItemInfo &versionInfo);
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, LauncherItemInfo &versionInfo);
|
||||
void registerLauncherItemInfoMetaType();
|
27
src/frameworkdbus/types/launcheriteminfolist.cpp
Normal file
27
src/frameworkdbus/types/launcheriteminfolist.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: LiLinling <lilinling_cm@deepin.com>
|
||||
*
|
||||
* Maintainer: LiLinling <lilinling_cm@deepin.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "launcheriteminfolist.h"
|
||||
|
||||
void registerLauncherItemInfoListMetaType()
|
||||
{
|
||||
qRegisterMetaType<LauncherItemInfo>("ItemInfoList");
|
||||
qDBusRegisterMetaType<LauncherItemInfoList>();
|
||||
}
|
32
src/frameworkdbus/types/launcheriteminfolist.h
Normal file
32
src/frameworkdbus/types/launcheriteminfolist.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: LiLinling <lilinling_cm@deepin.com>
|
||||
*
|
||||
* Maintainer: LiLinling <lilinling_cm@deepin.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "launcheriteminfo.h"
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
typedef QList<LauncherItemInfo> LauncherItemInfoList;
|
||||
|
||||
Q_DECLARE_METATYPE(LauncherItemInfoList)
|
||||
|
||||
void registerLauncherItemInfoListMetaType();
|
50
src/frameworkdbus/types/rect.cpp
Normal file
50
src/frameworkdbus/types/rect.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "rect.h"
|
||||
#include <QDebug>
|
||||
|
||||
Rect::Rect()
|
||||
: X(0)
|
||||
, Y(0)
|
||||
, Width(0)
|
||||
, Height(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const Rect &rect)
|
||||
{
|
||||
debug << QString("Rect(%1, %2, %3, %4)").arg(rect.X)
|
||||
.arg(rect.Y)
|
||||
.arg(rect.Width)
|
||||
.arg(rect.Height);
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
Rect::operator QRect() const
|
||||
{
|
||||
return QRect(X, Y, Width, Height);
|
||||
}
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &arg, const Rect &rect)
|
||||
{
|
||||
arg.beginStructure();
|
||||
arg << rect.X << rect.Y << rect.Width << rect.Height;
|
||||
arg.endStructure();
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
const QDBusArgument &operator>>(const QDBusArgument &arg, Rect &rect)
|
||||
{
|
||||
arg.beginStructure();
|
||||
arg >> rect.X >> rect.Y >> rect.Width >> rect.Height;
|
||||
arg.endStructure();
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
void registerRectMetaType()
|
||||
{
|
||||
qRegisterMetaType<Rect>("Rect");
|
||||
qDBusRegisterMetaType<Rect>();
|
||||
}
|
25
src/frameworkdbus/types/rect.h
Normal file
25
src/frameworkdbus/types/rect.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef DOCKRECT_H
|
||||
#define DOCKRECT_H
|
||||
|
||||
#include <QRect>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
struct Rect
|
||||
{
|
||||
public:
|
||||
Rect();
|
||||
operator QRect() const;
|
||||
|
||||
friend QDebug operator<<(QDebug debug, const Rect &rect);
|
||||
friend const QDBusArgument &operator>>(const QDBusArgument &arg, Rect &rect);
|
||||
friend QDBusArgument &operator<<(QDBusArgument &arg, const Rect &rect);
|
||||
|
||||
private:
|
||||
qint32 X, Y, Width, Height;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Rect)
|
||||
|
||||
void registerRectMetaType();
|
||||
|
||||
#endif // DOCKRECT_H
|
169
src/lib/basedir.cpp
Normal file
169
src/lib/basedir.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "basedir.h"
|
||||
#include "dfile.h"
|
||||
#include "dstring.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
BaseDir::BaseDir()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string BaseDir::homeDir()
|
||||
{
|
||||
char *home = getenv("HOME");
|
||||
if (!home)
|
||||
return "";
|
||||
|
||||
return std::string(home) + "/";
|
||||
}
|
||||
|
||||
std::string BaseDir::uerDataDir()
|
||||
{
|
||||
// default $HOME/.local/share
|
||||
std::string home = homeDir();
|
||||
std::string defaultDir = home.size() > 0 ? home + ".local/share/" : "";
|
||||
const char *xdgDataHomePtr = getenv("XDG_DATA_HOME");
|
||||
if (!xdgDataHomePtr)
|
||||
return defaultDir;
|
||||
|
||||
if (!DFile::isAbs(xdgDataHomePtr))
|
||||
return defaultDir;
|
||||
|
||||
return std::string(xdgDataHomePtr) + "/";
|
||||
}
|
||||
|
||||
std::vector<std::string> BaseDir::sysDataDirs()
|
||||
{
|
||||
std::vector<std::string> defaultDirs {"/usr/local/share/", "/usr/share/"};
|
||||
const char *xdgDataDirsPtr = getenv("XDG_DATA_DIRS");
|
||||
if (!xdgDataDirsPtr)
|
||||
return defaultDirs;
|
||||
|
||||
std::string xdgDataDirsStr(xdgDataDirsPtr);
|
||||
std::vector<std::string> xdgDataDirs = DString::splitStr(xdgDataDirsStr, ':');
|
||||
if (xdgDataDirs.size() == 0)
|
||||
return defaultDirs;
|
||||
|
||||
filterNotAbs(xdgDataDirs);
|
||||
addSuffixSlash(xdgDataDirs);
|
||||
return xdgDataDirs;
|
||||
}
|
||||
|
||||
std::string BaseDir::userConfigDir()
|
||||
{
|
||||
// default $HOME/.config
|
||||
std::string defaultDir = homeDir() + ".config/";
|
||||
const char *xdgConfigHomePtr = getenv("XDG_CONFIG_HOME");
|
||||
if (!xdgConfigHomePtr)
|
||||
return defaultDir;
|
||||
|
||||
std::string xdgConfigHome(xdgConfigHomePtr);
|
||||
if (!DFile::isAbs(xdgConfigHome))
|
||||
return defaultDir;
|
||||
|
||||
return xdgConfigHome + "/";
|
||||
}
|
||||
|
||||
std::vector<std::string> BaseDir::sysConfigDirs()
|
||||
{
|
||||
std::vector<std::string> defaultDirs {"/etc/xdg/"};
|
||||
const char *xdgConfigDirsPtr = getenv("XDG_CONFIG_DIRS");
|
||||
if (!xdgConfigDirsPtr)
|
||||
return defaultDirs;
|
||||
|
||||
std::string xdgConfigDirsStr(xdgConfigDirsPtr);
|
||||
std::vector<std::string> xdgConfigDirs = DString::splitStr(xdgConfigDirsStr, ':');
|
||||
if (xdgConfigDirs.size() == 0)
|
||||
return defaultDirs;
|
||||
|
||||
filterNotAbs(xdgConfigDirs);
|
||||
addSuffixSlash(xdgConfigDirs);
|
||||
return xdgConfigDirs;
|
||||
}
|
||||
|
||||
std::string BaseDir::userCacheDir()
|
||||
{
|
||||
std::string home = homeDir();
|
||||
std::string defaultDir = home.size() > 0 ? home + ".cache/" : "";
|
||||
const char *xdgCacheHomePtr = getenv("XDG_CACHE_HOME");
|
||||
if (!xdgCacheHomePtr)
|
||||
return defaultDir;
|
||||
|
||||
std::string xdgCacheHome(xdgCacheHomePtr);
|
||||
if (!DFile::isAbs(xdgCacheHome))
|
||||
return defaultDir;
|
||||
|
||||
return xdgCacheHome + "/";
|
||||
}
|
||||
|
||||
std::string BaseDir::userAppDir()
|
||||
{
|
||||
std::string dataDir = uerDataDir();
|
||||
return dataDir.size() > 0 ? dataDir + "appliations/" : "";
|
||||
}
|
||||
|
||||
std::vector<std::string> BaseDir::sysAppDirs()
|
||||
{
|
||||
auto dataDirs = sysDataDirs();
|
||||
std::vector<std::string> sysAppDirs(dataDirs.size());
|
||||
std::transform(dataDirs.begin(), dataDirs.end(), sysAppDirs.begin(),
|
||||
[](std::string dir) -> std::string {return dir + "applications/";});
|
||||
return sysAppDirs;
|
||||
}
|
||||
|
||||
std::vector<std::string> BaseDir::appDirs()
|
||||
{
|
||||
std::vector<std::string> appDirs = sysAppDirs();
|
||||
appDirs.push_back(userAppDir());
|
||||
return appDirs;
|
||||
}
|
||||
|
||||
std::vector<std::string> BaseDir::autoStartDirs()
|
||||
{
|
||||
std::vector<std::string> autoStartDirs = sysConfigDirs();
|
||||
autoStartDirs.push_back(userConfigDir());
|
||||
std::transform(autoStartDirs.begin(), autoStartDirs.end(), autoStartDirs.begin(),
|
||||
[](std::string dir) -> std::string {return dir + "autostart/";});
|
||||
|
||||
return autoStartDirs;
|
||||
}
|
||||
|
||||
void BaseDir::filterNotAbs(std::vector<std::string> &dirs)
|
||||
{
|
||||
for (auto iter = dirs.begin(); iter != dirs.end();) { // erase element in vector
|
||||
if (!DFile::isAbs(*iter))
|
||||
iter = dirs.erase(iter);
|
||||
else
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseDir::addSuffixSlash(std::vector<std::string> &dirs)
|
||||
{
|
||||
for (auto &dir : dirs) {
|
||||
if (!DString::endWith(dir, "/"))
|
||||
dir += "/";
|
||||
}
|
||||
}
|
50
src/lib/basedir.h
Normal file
50
src/lib/basedir.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BASEDIR_H
|
||||
#define BASEDIR_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// 基础目录类, 目录结尾统一包含斜杠/
|
||||
class BaseDir
|
||||
{
|
||||
public:
|
||||
BaseDir();
|
||||
|
||||
static std::string homeDir();
|
||||
static std::string uerDataDir();
|
||||
static std::vector<std::string> sysDataDirs();
|
||||
static std::string userConfigDir();
|
||||
static std::vector<std::string> sysConfigDirs();
|
||||
static std::string userCacheDir();
|
||||
static std::string userAppDir();
|
||||
static std::vector<std::string> sysAppDirs();
|
||||
static std::vector<std::string> appDirs();
|
||||
static std::vector<std::string> autoStartDirs();
|
||||
|
||||
private:
|
||||
static void filterNotAbs(std::vector<std::string> &dirs);
|
||||
static void addSuffixSlash(std::vector<std::string> &dirs);
|
||||
};
|
||||
|
||||
#endif // BASEDIR_H
|
380
src/lib/desktopinfo.cpp
Normal file
380
src/lib/desktopinfo.cpp
Normal file
@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "desktopinfo.h"
|
||||
#include "locale.h"
|
||||
#include "unistd.h"
|
||||
#include "dstring.h"
|
||||
#include "dfile.h"
|
||||
#include "basedir.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <dirent.h>
|
||||
|
||||
std::vector<std::string> DesktopInfo::currentDesktops;
|
||||
|
||||
DesktopInfo::DesktopInfo(const std::string &_fileName)
|
||||
: kf(KeyFile())
|
||||
, fileName(_fileName)
|
||||
, isValid(true)
|
||||
{
|
||||
if (!DString::endWith(fileName, ".desktop"))
|
||||
fileName += ".desktop";
|
||||
|
||||
if (!DFile::isAbs(fileName)) {
|
||||
// fileName是文件名,增加目录
|
||||
bool isExisted = false;
|
||||
for (const auto &dir : BaseDir::appDirs()) {
|
||||
fileName = dir + fileName;
|
||||
if (DFile::isExisted(fileName)) {
|
||||
isExisted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isExisted) {
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
kf.loadFile(fileName);
|
||||
|
||||
// check DesktopInfo valid
|
||||
if (fileName.find(".desktop") == std::string::npos)
|
||||
isValid = false;
|
||||
|
||||
std::vector<std::string> mainKeys = kf.getMainKeys();
|
||||
if (mainKeys.size() == 0)
|
||||
isValid = false;
|
||||
|
||||
bool found = std::any_of(mainKeys.begin(), mainKeys.end(),
|
||||
[](const auto &key) {return key == MainSection;});
|
||||
|
||||
if (!found)
|
||||
isValid = false;
|
||||
|
||||
if (kf.getStr(MainSection, KeyType) != TypeApplication)
|
||||
isValid = false;
|
||||
|
||||
name = kf.getLocaleStr(MainSection, KeyName, "");
|
||||
icon = kf.getStr(MainSection, KeyIcon);
|
||||
id = getId();
|
||||
}
|
||||
|
||||
DesktopInfo::~DesktopInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getFileName()
|
||||
{
|
||||
return fileName;
|
||||
}
|
||||
|
||||
bool DesktopInfo::isValidDesktop()
|
||||
{
|
||||
return isValid;
|
||||
}
|
||||
|
||||
bool DesktopInfo::shouldShow()
|
||||
{
|
||||
if (getNoDisplay() || getIsHidden())
|
||||
return false;
|
||||
|
||||
std::vector<std::string> desktopEnvs;
|
||||
return getShowIn(desktopEnvs);
|
||||
}
|
||||
|
||||
bool DesktopInfo::getNoDisplay()
|
||||
{
|
||||
return kf.getBool(MainSection, KeyNoDisplay);
|
||||
}
|
||||
|
||||
bool DesktopInfo::getIsHidden()
|
||||
{
|
||||
return kf.getBool(MainSection, KeyHidden);
|
||||
}
|
||||
|
||||
bool DesktopInfo::getShowIn(std::vector<std::string> desktopEnvs)
|
||||
{
|
||||
if (desktopEnvs.size() == 0) {
|
||||
if (currentDesktops.size() == 0) {
|
||||
const char *env = getenv(envDesktopEnv.c_str());
|
||||
const auto &desktop = DString::splitChars(env, ':');
|
||||
currentDesktops.assign(desktop.begin(), desktop.end());
|
||||
}
|
||||
desktopEnvs.assign(currentDesktops.begin(), currentDesktops.end());
|
||||
}
|
||||
|
||||
std::vector<std::string> onlyShowIn = kf.getStrList(MainSection, KeyOnlyShowIn);
|
||||
std::vector<std::string> notShowIn = kf.getStrList(MainSection, KeyNotShowIn);
|
||||
|
||||
for (const auto &desktop : desktopEnvs) {
|
||||
bool ret = std::any_of(onlyShowIn.begin(), onlyShowIn.end(),
|
||||
[&desktop](const auto &d) {return d == desktop;});
|
||||
if (ret)
|
||||
return true;
|
||||
|
||||
ret = std::any_of(notShowIn.begin(), notShowIn.end(),
|
||||
[&desktop](const auto &d) {return d == desktop;});
|
||||
if (ret)
|
||||
return false;
|
||||
}
|
||||
|
||||
return onlyShowIn.size() == 0;
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getExecutable()
|
||||
{
|
||||
return kf.getStr(MainSection, KeyExec);
|
||||
}
|
||||
|
||||
bool DesktopInfo::isExecutableOk()
|
||||
{
|
||||
// 检查TryExec字段
|
||||
std::string value = getTryExec();
|
||||
std::vector<std::string> parts = DString::splitStr(value, ' ');
|
||||
if (parts.size() > 0 ) {
|
||||
value.assign(parts[0]);
|
||||
DString::delQuote(value);
|
||||
if (strstr(value.c_str(), "/") && DFile::isExisted(value))
|
||||
return true;
|
||||
else
|
||||
return findExecutable(value);
|
||||
}
|
||||
|
||||
// 检查Exec字段
|
||||
value.assign(getExecutable());
|
||||
parts.clear();
|
||||
parts = DString::splitStr(value, ' ');
|
||||
if (parts.size() > 0) {
|
||||
value.assign(parts[0]);
|
||||
DString::delQuote(value);
|
||||
if (strstr(value.c_str(), "/") && DFile::isExisted(value))
|
||||
return true;
|
||||
else
|
||||
return findExecutable(value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DesktopInfo::isInstalled()
|
||||
{
|
||||
const char *name = fileName.c_str();
|
||||
const char *found = strstr(name, "/applications/");
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
auto appDirs = BaseDir::appDirs();
|
||||
return std::any_of(appDirs.begin(), appDirs.end(),
|
||||
[&name, &found] (std::string dir) -> bool {return strneq(dir.c_str(), name, size_t(found - name));});
|
||||
}
|
||||
|
||||
std::vector<DesktopAction> DesktopInfo::getActions()
|
||||
{
|
||||
std::vector<DesktopAction> actions;
|
||||
for (const auto &mainKey : kf.getMainKeys()) {
|
||||
if (DString::startWith(mainKey, "Desktop Action")
|
||||
|| DString::endWith(mainKey, "Shortcut Group")) {
|
||||
DesktopAction action;
|
||||
action.name = kf.getLocaleStr(mainKey, KeyName, "");
|
||||
action.exec = kf.getStr(mainKey, KeyExec);
|
||||
actions.push_back(action);
|
||||
}
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
// 使用appId获取DesktopInfo需检查有效性
|
||||
DesktopInfo DesktopInfo::getDesktopInfoById(std::string appId)
|
||||
{
|
||||
if (!DString::endWith(appId, ".desktop"))
|
||||
appId += ".desktop";
|
||||
|
||||
for (const auto & dir : BaseDir::appDirs()) {
|
||||
std::string filePath = dir + appId;
|
||||
//检测文件有效性
|
||||
if (DFile::isExisted(filePath)) {
|
||||
return DesktopInfo(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
return DesktopInfo("");
|
||||
}
|
||||
|
||||
// TryExec is Path to an executable file on disk used to determine if the program is actually installed
|
||||
std::string DesktopInfo::getTryExec()
|
||||
{
|
||||
return kf.getStr(MainSection, KeyTryExec);
|
||||
}
|
||||
|
||||
// 按$PATH路径查找执行文件
|
||||
bool DesktopInfo::findExecutable(std::string &exec)
|
||||
{
|
||||
static const char *path = getenv("PATH");
|
||||
static std::vector<std::string> paths = DString::splitChars(path, ':');
|
||||
return std::any_of(paths.begin(), paths.end(), [&exec](std::string path) {return DFile::isExisted(path + "/" +exec);});
|
||||
}
|
||||
|
||||
// filename must has suffix desktopExt
|
||||
// example:
|
||||
// /usr/share/applications/a.desktop -> a
|
||||
// /usr/share/applications/kde4/a.desktop -> kde4/a
|
||||
// /xxxx/dir/a.desktop -> /xxxx/dir/a
|
||||
std::string DesktopInfo::getId()
|
||||
{
|
||||
if (!id.empty())
|
||||
return id;
|
||||
|
||||
std::string idStr;
|
||||
auto const suffixPos = fileName.find(".desktop");
|
||||
if (suffixPos == std::string::npos)
|
||||
return "";
|
||||
|
||||
idStr = fileName.substr(0, fileName.size() - 8); // trim suffix
|
||||
size_t dirPos = idStr.find("/applications/");
|
||||
if (dirPos == std::string::npos)
|
||||
return "";
|
||||
|
||||
std::string baseDir(idStr.substr(0, dirPos + 14)); // length of "/applications/" is 14
|
||||
std::vector<std::string> appDirs = BaseDir::appDirs();
|
||||
bool installed = std::any_of(appDirs.begin(), appDirs.end(),
|
||||
[&baseDir](const auto &dir) {return dir == baseDir;});
|
||||
|
||||
if (installed) {
|
||||
id = idStr.substr(baseDir.size(), idStr.size());
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getGenericName()
|
||||
{
|
||||
return kf.getLocaleStr(MainSection, KeyGenericName, "");
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getIcon()
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
|
||||
std::string DesktopInfo::getCommandLine()
|
||||
{
|
||||
return kf.getStr(MainSection, KeyExec);
|
||||
}
|
||||
|
||||
std::vector<std::string> DesktopInfo::getKeywords()
|
||||
{
|
||||
return kf.getLocaleStrList(MainSection, KeyKeywords, "");
|
||||
}
|
||||
|
||||
std::vector<std::string> DesktopInfo::getCategories()
|
||||
{
|
||||
return kf.getStrList(MainSection, KeyCategories);
|
||||
}
|
||||
|
||||
// class AppsDir
|
||||
AppsDir::AppsDir(const std::string &dirPath)
|
||||
: path(dirPath)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AppsDir::~AppsDir()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string AppsDir::getPath()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
// 获取目录对应的应用名称
|
||||
std::map<std::string, bool> AppsDir::getAppNames()
|
||||
{
|
||||
DIR* dp;
|
||||
struct dirent* ep;
|
||||
|
||||
dp = opendir(path.c_str());
|
||||
if (dp == nullptr)
|
||||
{
|
||||
std::cout << "Couldn't open directory " << path << std::endl;
|
||||
return appNames;
|
||||
}
|
||||
|
||||
while ((ep = readdir(dp))) {
|
||||
if (ep->d_type != DT_REG && ep->d_type != DT_LNK)
|
||||
continue;
|
||||
|
||||
if (!DString::endWith(ep->d_name, ".desktop"))
|
||||
continue;
|
||||
|
||||
appNames.insert({ep->d_name, true});
|
||||
}
|
||||
closedir(dp);
|
||||
|
||||
return appNames;
|
||||
}
|
||||
|
||||
// 获取所有应用信息
|
||||
std::vector<DesktopInfo> AppsDir::getAllDesktopInfos()
|
||||
{
|
||||
std::map<std::string, bool> recoder;
|
||||
std::vector<DesktopInfo> desktopInfos;
|
||||
|
||||
for (auto dir : BaseDir::appDirs()) {
|
||||
AppsDir appsDir(dir);
|
||||
std::map<std::string, bool> appNames = appsDir.getAppNames();
|
||||
if (appNames.size() == 0)
|
||||
continue;
|
||||
|
||||
for (const auto &iter : appNames) {
|
||||
if (recoder.find(iter.first) != recoder.end())
|
||||
continue;
|
||||
|
||||
std::string filePath = dir + iter.first;
|
||||
DesktopInfo desktopInfo(filePath);
|
||||
if (!desktopInfo.isValidDesktop())
|
||||
continue;
|
||||
|
||||
if (!desktopInfo.shouldShow())
|
||||
continue;
|
||||
|
||||
desktopInfos.push_back(std::move(desktopInfo));
|
||||
recoder[iter.first] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return desktopInfos;
|
||||
}
|
||||
|
121
src/lib/desktopinfo.h
Normal file
121
src/lib/desktopinfo.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DESKTOPINFO_H
|
||||
#define DESKTOPINFO_H
|
||||
|
||||
#include "keyfile.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
const std::string MainSection = "Desktop Entry";
|
||||
const std::string KeyType = "Type";
|
||||
const std::string KeyVersion = "Version";
|
||||
const std::string KeyName = "Name";
|
||||
const std::string KeyGenericName = "GenericName";
|
||||
const std::string KeyNoDisplay = "NoDisplay";
|
||||
const std::string KeyComment = "Comment";
|
||||
const std::string KeyIcon = "Icon";
|
||||
const std::string KeyHidden = "Hidden";
|
||||
const std::string KeyOnlyShowIn = "OnlyShowIn";
|
||||
const std::string KeyNotShowIn = "NotShowIn";
|
||||
const std::string KeyTryExec = "TryExec";
|
||||
const std::string KeyExec = "Exec";
|
||||
const std::string KeyPath = "Path";
|
||||
const std::string KeyTerminal = "Terminal";
|
||||
const std::string KeyMimeType = "MimeType";
|
||||
const std::string KeyCategories = "Categories";
|
||||
const std::string KeyKeywords = "Keywords";
|
||||
const std::string KeyStartupNotify = "StartupNotify";
|
||||
const std::string KeyStartupWMClass = "StartupWMClass";
|
||||
const std::string KeyURL = "URL";
|
||||
const std::string KeyActions = "Actions";
|
||||
const std::string KeyDBusActivatable = "DBusActivatable";
|
||||
|
||||
const std::string TypeApplication = "Application";
|
||||
const std::string TypeLink = "Link";
|
||||
const std::string TypeDirectory = "Directory";
|
||||
|
||||
const std::string envDesktopEnv = "XDG_CURRENT_DESKTOP";
|
||||
|
||||
typedef struct DesktopAction {
|
||||
std::string section;
|
||||
std::string name;
|
||||
std::string exec;
|
||||
} DesktopAction;
|
||||
|
||||
// 应用Desktop信息类
|
||||
class DesktopInfo {
|
||||
public:
|
||||
explicit DesktopInfo(const std::string &_fileName);
|
||||
~DesktopInfo();
|
||||
|
||||
std::string getFileName();
|
||||
std::string getExecutable();
|
||||
bool isValidDesktop();
|
||||
bool shouldShow();
|
||||
bool getNoDisplay();
|
||||
bool getIsHidden();
|
||||
bool getShowIn(std::vector<std::string> desktopEnvs);
|
||||
bool isExecutableOk();
|
||||
bool isInstalled();
|
||||
std::vector<DesktopAction> getActions();
|
||||
static DesktopInfo getDesktopInfoById(std::string appId);
|
||||
|
||||
std::string getId();
|
||||
std::string getGenericName();
|
||||
std::string getName();
|
||||
std::string getIcon();
|
||||
std::string getCommandLine();
|
||||
std::vector<std::string> getKeywords();
|
||||
std::vector<std::string> getCategories();
|
||||
|
||||
KeyFile kf;
|
||||
|
||||
private:
|
||||
std::string getTryExec();
|
||||
bool findExecutable(std::string &exec);
|
||||
std::string fileName;
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string icon;
|
||||
std::string overRideExec;
|
||||
bool isValid;
|
||||
static std::vector<std::string> currentDesktops;
|
||||
};
|
||||
|
||||
// 应用目录类
|
||||
class AppsDir {
|
||||
public:
|
||||
explicit AppsDir(const std::string &dirPath);
|
||||
~AppsDir();
|
||||
|
||||
std::string getPath();
|
||||
std::map<std::string, bool> getAppNames();
|
||||
static std::vector<DesktopInfo> getAllDesktopInfos();
|
||||
|
||||
private:
|
||||
std::string path;
|
||||
std::map<std::string, bool> appNames;
|
||||
};
|
||||
|
||||
#endif // DESKTOPINFO_H
|
79
src/lib/dfile.cpp
Normal file
79
src/lib/dfile.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dfile.h"
|
||||
#include "macro.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
DFile::DFile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool DFile::isAbs(std::string file)
|
||||
{
|
||||
char resolved_path[MAX_FILEPATH_LEN];
|
||||
if (realpath(file.c_str(), resolved_path)) {
|
||||
std::string filePath(resolved_path);
|
||||
if (filePath == file)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DFile::isExisted(std::string file)
|
||||
{
|
||||
return !access(file.c_str(), F_OK);
|
||||
}
|
||||
|
||||
std::string DFile::dir(std::string file)
|
||||
{
|
||||
std::string ret;
|
||||
if (isAbs(file)) {
|
||||
size_t pos = file.find_last_of("/");
|
||||
if (pos != std::string::npos) {
|
||||
ret.assign(file, 0, pos + 1); // 包含结尾斜杠/
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string DFile::base(std::string file)
|
||||
{
|
||||
std::string ret;
|
||||
if (strstr(file.c_str(), "/")) { // 包含路径
|
||||
size_t pos = file.find_last_of("/");
|
||||
if (pos != std::string::npos) {
|
||||
ret.assign(file, pos + 1, file.size() - pos); // 去除路径
|
||||
}
|
||||
}
|
||||
|
||||
size_t pos = file.find_last_of("."); // 去除后缀
|
||||
if (pos != std::string::npos) {
|
||||
ret.assign(file, 0, pos + 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
37
src/lib/dfile.h
Normal file
37
src/lib/dfile.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DFILE_H
|
||||
#define DFILE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class DFile
|
||||
{
|
||||
public:
|
||||
explicit DFile();
|
||||
static bool isAbs(std::string file);
|
||||
static bool isExisted(std::string file);
|
||||
static std::string dir(std::string file);
|
||||
static std::string base(std::string file);
|
||||
};
|
||||
|
||||
#endif // DFILE_H
|
210
src/lib/dlocale.cpp
Normal file
210
src/lib/dlocale.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dlocale.h"
|
||||
#include "dstring.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define ComponentCodeset 1
|
||||
#define ComponentTerritory 2
|
||||
#define ComponentModifier 4
|
||||
|
||||
#define MAXLINELEN 256
|
||||
|
||||
const char *aliasFile = "/usr/share/locale/locale.alias";
|
||||
const char charUscore = '_';
|
||||
const char charDot = '.';
|
||||
const char charAt = '@';
|
||||
|
||||
Locale::Locale()
|
||||
{
|
||||
pthread_mutex_init(&languageNames.mutex, nullptr);
|
||||
|
||||
// init aliases
|
||||
FILE *fp = fopen(aliasFile, "r");
|
||||
if (fp) {
|
||||
|
||||
char data[MAXLINELEN] = {0};
|
||||
std::string line;
|
||||
std::vector<std::string> parts;
|
||||
while (fgets(data, MAXLINELEN, fp)) {
|
||||
char *start = &data[0];
|
||||
char *end = start;
|
||||
|
||||
// 移除行首
|
||||
while (strneq(start, " ", 1) || strneq(start, "\t", 1))
|
||||
start++;
|
||||
|
||||
// 过滤注释行和空行
|
||||
if (strneq(start, "#", 1) || strneq(start, "\n", 1))
|
||||
continue;
|
||||
|
||||
while (!strneq(end, "\n", 1))
|
||||
end++;
|
||||
|
||||
// 移除行尾
|
||||
while (strneq(end, "\n", 1) || strneq(end, "\r", 1)
|
||||
|| strneq(end, " ", 1) || strneq(end, "\t", 1))
|
||||
end--;
|
||||
|
||||
line.assign(start, ulong(end - start + 1));
|
||||
parts = DString::splitStr(line, ' ');
|
||||
// 使用\t分割
|
||||
if (parts.size() != 2)
|
||||
parts = DString::splitStr(line, '\t');
|
||||
|
||||
if (parts.size() == 2) {
|
||||
aliases[parts[0]] = parts[1];
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
// wayland environment is useful?
|
||||
// ExplodeLocale Break an X/Open style locale specification into components
|
||||
Locale::Components Locale::explodeLocale(std::string locale)
|
||||
{
|
||||
Components cmp;
|
||||
std::vector<std::string> parts;
|
||||
if (locale.find(charAt) != std::string::npos) {
|
||||
parts = DString::splitStr(locale, charAt);
|
||||
if (parts.size() == 2) {
|
||||
cmp.modifier = parts[1];
|
||||
locale = parts[0];
|
||||
cmp.mask |= ComponentModifier;
|
||||
}
|
||||
}
|
||||
|
||||
if (locale.find(charDot) != std::string::npos) {
|
||||
parts = DString::splitStr(locale, charDot);
|
||||
if (parts.size() == 2) {
|
||||
cmp.codeset = parts[1];
|
||||
locale = locale[0];
|
||||
cmp.mask |= ComponentCodeset;
|
||||
}
|
||||
}
|
||||
|
||||
if (locale.find(charUscore) != std::string::npos) {
|
||||
parts = DString::splitStr(locale, charUscore);
|
||||
if (parts.size() == 2) {
|
||||
cmp.territory = parts[1];
|
||||
locale = parts[0];
|
||||
cmp.mask |= ComponentTerritory;
|
||||
}
|
||||
}
|
||||
|
||||
cmp.language = locale;
|
||||
return cmp;
|
||||
}
|
||||
|
||||
std::string Locale::guessCategoryValue(std::string categoryName)
|
||||
{
|
||||
// The highest priority value is the 'LANGUAGE' environment
|
||||
// variable. This is a GNU extension.
|
||||
const char *language = getenv("LANGUAGE");
|
||||
if (language)
|
||||
return language;
|
||||
|
||||
// Setting of LC_ALL overwrites all other.
|
||||
const char *lcAll = getenv("LC_ALL");
|
||||
if (lcAll)
|
||||
return lcAll;
|
||||
|
||||
// Next comes the name of the desired category.
|
||||
const char *name = getenv(categoryName.c_str());
|
||||
if (name)
|
||||
return name;
|
||||
|
||||
// Last possibility is the LANG environment variable.
|
||||
const char *lang = getenv("LANG");
|
||||
if (lang)
|
||||
return lang;
|
||||
|
||||
return "C";
|
||||
}
|
||||
|
||||
std::string Locale::unaliasLang(std::string lang)
|
||||
{
|
||||
if (aliases.find(lang) != aliases.end())
|
||||
return aliases[lang];
|
||||
else
|
||||
return lang;
|
||||
}
|
||||
|
||||
// wayland environment is useful?
|
||||
/*
|
||||
* Compute all interesting variants for a given locale name -
|
||||
* by stripping off different components of the value.
|
||||
*
|
||||
* For simplicity, we assume that the locale is in
|
||||
* X/Open format: language[_territory][.codeset][@modifier]
|
||||
*/
|
||||
std::vector<std::string> Locale::getLocaleVariants(const std::string &locale)
|
||||
{
|
||||
auto cmp = explodeLocale(locale);
|
||||
uint mask = cmp.mask;
|
||||
std::vector<std::string> variants;
|
||||
for (uint i = 0; i <= mask; i++) {
|
||||
uint j = mask - i;
|
||||
//if ((j & ^mask) == 0) {
|
||||
std::string var(cmp.language);
|
||||
if (j & ComponentTerritory)
|
||||
var = var + charUscore + cmp.territory;
|
||||
if (j & ComponentCodeset)
|
||||
var = var + charDot + cmp.codeset;
|
||||
if (j & ComponentModifier)
|
||||
var = var + charAt + cmp.modifier;
|
||||
|
||||
variants.push_back(var);
|
||||
//}
|
||||
}
|
||||
|
||||
return variants;
|
||||
}
|
||||
|
||||
std::vector<std::string> Locale::getLanguageNames()
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
std::string value(guessCategoryValue("LC_MESSAGES"));
|
||||
if (value.empty()) {
|
||||
names.push_back(value);
|
||||
return names;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&languageNames.mutex);
|
||||
if (languageNames.language != value) {
|
||||
languageNames.language = value;
|
||||
languageNames.names.clear();
|
||||
std::vector<std::string> langs = DString::splitStr(value, ':');
|
||||
for (const auto & lang : langs) {
|
||||
std::vector<std::string> localeVariant = getLocaleVariants(unaliasLang(lang));
|
||||
for (const auto & var : localeVariant)
|
||||
languageNames.names.push_back(var);
|
||||
}
|
||||
languageNames.names.push_back("C");
|
||||
}
|
||||
pthread_mutex_unlock(&languageNames.mutex);
|
||||
|
||||
return languageNames.names;
|
||||
}
|
66
src/lib/dlocale.h
Normal file
66
src/lib/dlocale.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOCALE_H
|
||||
#define LOCALE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// 本地化类
|
||||
class Locale {
|
||||
struct LanguageNameCache {
|
||||
std::string language;
|
||||
std::vector<std::string> names;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
struct Components {
|
||||
Components() : mask(0) {} // 数字必须初始化
|
||||
std::string language;
|
||||
std::string territory;
|
||||
std::string codeset;
|
||||
std::string modifier;
|
||||
uint mask;
|
||||
};
|
||||
|
||||
public:
|
||||
std::vector<std::string> getLocaleVariants(const std::string &locale);
|
||||
std::vector<std::string> getLanguageNames();
|
||||
static inline Locale *instance() {
|
||||
static Locale instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
private:
|
||||
Locale();
|
||||
Locale(const Locale &);
|
||||
Locale& operator= (const Locale &);
|
||||
|
||||
Components explodeLocale(std::string locale);
|
||||
std::string guessCategoryValue(std::string categoryName);
|
||||
std::string unaliasLang(std::string);
|
||||
std::map<std::string, std::string> aliases;
|
||||
LanguageNameCache languageNames;
|
||||
};
|
||||
|
||||
#endif
|
147
src/lib/dstring.cpp
Normal file
147
src/lib/dstring.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dstring.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
DString::DString()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DString::~DString()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::string> DString::splitChars(const char *cs, char c)
|
||||
{
|
||||
assert(cs);
|
||||
|
||||
std::vector<std::string> ret;
|
||||
unsigned long idx = 0;
|
||||
unsigned long size = strlen(cs);
|
||||
bool found = false;
|
||||
std::string sub;
|
||||
for (unsigned long i=0; i < size; i++) {
|
||||
if (!strneq(&cs[i], &c, 1))
|
||||
continue;
|
||||
|
||||
sub.assign(cs, found ? idx+1:idx, found ? i-idx-1:i-idx);
|
||||
if (idx < i && !sub.empty()) {
|
||||
ret.push_back(sub);
|
||||
}
|
||||
idx = i;
|
||||
found = true;
|
||||
}
|
||||
sub.assign(cs, found ? idx+1:idx, found ? size-idx-1:size-idx);
|
||||
if (idx < size && !sub.empty()) {
|
||||
ret.push_back(sub);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> DString::splitStr(const std::string &str, char c)
|
||||
{
|
||||
return splitChars(str.c_str(), c);
|
||||
}
|
||||
|
||||
std::vector<std::string> DString::splitVectorChars(const std::vector<char> &content, size_t length, char c)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
size_t pos = 0;
|
||||
bool hasChar = true;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (content[i] == c && i > pos && hasChar) {
|
||||
std::string str;
|
||||
for (size_t j = pos; j <= i; j++) {
|
||||
str += std::string(1, content[j]);
|
||||
}
|
||||
ret.push_back(str);
|
||||
pos = i + 1;
|
||||
hasChar = false;
|
||||
} else {
|
||||
hasChar = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DString::startWith(const char *chars, const char *prefix)
|
||||
{
|
||||
assert(chars);
|
||||
assert(prefix);
|
||||
|
||||
size_t len;
|
||||
len = strlen(prefix);
|
||||
return strneq(chars, prefix, len);
|
||||
}
|
||||
|
||||
bool DString::startWith(const std::string &str, const std::string &prefix)
|
||||
{
|
||||
return startWith(str.c_str(), prefix.c_str());
|
||||
}
|
||||
|
||||
bool DString::endWith(const char *chars, const char *suffix)
|
||||
{
|
||||
assert(chars);
|
||||
assert(suffix);
|
||||
|
||||
size_t charsLen = strlen(chars);
|
||||
size_t suffixLen = strlen(suffix);
|
||||
|
||||
if (charsLen == 0 || charsLen < suffixLen)
|
||||
return false;
|
||||
|
||||
return memcmp(chars + charsLen - suffixLen, suffix, suffixLen) == 0;
|
||||
}
|
||||
|
||||
bool DString::endWith(const std::string &str, const std::string &suffix)
|
||||
{
|
||||
return endWith(str.c_str(), suffix.c_str());
|
||||
}
|
||||
|
||||
char *DString::delQuote(const char *chars)
|
||||
{
|
||||
char *data = nullptr;
|
||||
if (!chars)
|
||||
return data;
|
||||
|
||||
if (strneq(chars, "\"", 1) && strneq(chars + strlen(chars) - 1, "\"", 1)) {
|
||||
data = static_cast<char *>(calloc(1, strlen(chars) - 2));
|
||||
memcpy(data, chars + 1, strlen(chars) - 1);
|
||||
} else {
|
||||
data = static_cast<char *>(calloc(1, strlen(chars) + 1));
|
||||
memcpy(data, chars, strlen(chars) + 1);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void DString::delQuote(std::string &str)
|
||||
{
|
||||
while (*str.begin() == '\"' && *str.rbegin() == '\"')
|
||||
str.assign(str.substr(1, str.size() - 2));
|
||||
}
|
||||
|
56
src/lib/dstring.h
Normal file
56
src/lib/dstring.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DSTRING_H
|
||||
#define DSTRING_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#define streq(a,b) (strcmp((a),(b)) == 0)
|
||||
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
|
||||
#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
|
||||
#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
|
||||
|
||||
// 字符串操作
|
||||
class DString
|
||||
{
|
||||
public:
|
||||
DString();
|
||||
~DString();
|
||||
|
||||
// 字符串拆分
|
||||
static std::vector<std::string> splitChars(const char *cs, char c);
|
||||
static std::vector<std::string> splitStr(const std::string &str, char c);
|
||||
static std::vector<std::string> splitVectorChars(const std::vector<char> &content, size_t length, char c);
|
||||
// 字符串前缀判断
|
||||
static bool startWith(const char *chars, const char *prefix);
|
||||
static bool startWith(const std::string &str, const std::string &prefix);
|
||||
// 字符后缀判断
|
||||
static bool endWith(const char *chars, const char *suffix);
|
||||
static bool endWith(const std::string &str, const std::string &suffix);
|
||||
// 去除首尾引用
|
||||
static char *delQuote(const char *chars);
|
||||
static void delQuote(std::string &str);
|
||||
};
|
||||
|
||||
#endif // DSTRING_H
|
289
src/lib/keyfile.cpp
Normal file
289
src/lib/keyfile.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "keyfile.h"
|
||||
#include "dlocale.h"
|
||||
#include "dstring.h"
|
||||
#include "macro.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
KeyFile::KeyFile(char separtor)
|
||||
: fp(nullptr)
|
||||
, modified(false)
|
||||
, listSeparator(separtor)
|
||||
{
|
||||
}
|
||||
|
||||
KeyFile::~KeyFile()
|
||||
{
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool KeyFile::getBool(const std::string §ion, const std::string &key, bool defaultValue)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
return false;
|
||||
|
||||
std::string valueStr = mainKeyMap[section][key];
|
||||
bool value = defaultValue;
|
||||
if (valueStr == "true")
|
||||
value = true;
|
||||
else if (valueStr == "false")
|
||||
value = false;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// TODO
|
||||
std::vector<bool> KeyFile::getBoolList(const std::string §ion, const std::string &key, bool defaultValue)
|
||||
{
|
||||
std::vector<bool> tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int KeyFile::getInt(const std::string §ion, const std::string &key, int defaultValue)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
return defaultValue;
|
||||
|
||||
std::string valueStr = mainKeyMap[section][key];
|
||||
int value;
|
||||
try {
|
||||
value = std::stoi(valueStr);
|
||||
} catch (std::invalid_argument&) {
|
||||
value = defaultValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// TODO
|
||||
std::vector<int> KeyFile::getIntList(const std::string §ion, const std::string &key, int defaultValue)
|
||||
{
|
||||
std::vector<int> tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// TODO
|
||||
int64_t KeyFile::getInt64(const std::string §ion, const std::string &key, int64_t defaultValue)
|
||||
{
|
||||
return int64_t(0);
|
||||
}
|
||||
|
||||
// TODO
|
||||
float KeyFile::getFloat(const std::string §ion, const std::string &key, float defaultValue)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
std::string KeyFile::getStr(const std::string §ion, const std::string &key, std::string defaultValue)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
return defaultValue;
|
||||
|
||||
std::string valueStr = mainKeyMap[section][key];
|
||||
if (valueStr.empty())
|
||||
valueStr = defaultValue;
|
||||
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
bool KeyFile::containKey(const std::string §ion, const std::string &key)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
return false;
|
||||
|
||||
return mainKeyMap[section].find(key) != mainKeyMap[section].end();
|
||||
}
|
||||
|
||||
std::string KeyFile::getLocaleStr(const std::string §ion, const std::string &key, std::string defaultLocale)
|
||||
{
|
||||
std::vector<std::string> languages = defaultLocale.empty()
|
||||
? Locale::instance()->getLanguageNames()
|
||||
: Locale::instance()->getLocaleVariants(defaultLocale);
|
||||
|
||||
std::string translated;
|
||||
for (const auto &lang : languages) {
|
||||
translated.assign(getStr(section, key + "[" + lang + "]"));
|
||||
if (!translated.empty())
|
||||
return translated;
|
||||
}
|
||||
|
||||
// NOTE: not support key Gettext-Domain
|
||||
// fallback to default key
|
||||
return getStr(section, key);
|
||||
}
|
||||
|
||||
std::vector<std::string> KeyFile::getStrList(const std::string §ion, const std::string &key)
|
||||
{
|
||||
std::string value = getStr(section, key);
|
||||
return DString::splitStr(value, listSeparator);
|
||||
}
|
||||
|
||||
std::vector<std::string> KeyFile::getLocaleStrList(const std::string §ion, const std::string &key, std::string defaultLocale)
|
||||
{
|
||||
std::vector<std::string> languages = defaultLocale.empty()
|
||||
? Locale::instance()->getLanguageNames()
|
||||
: Locale::instance()->getLocaleVariants(defaultLocale);
|
||||
|
||||
std::vector<std::string> translated;
|
||||
for (const auto &lang : languages) {
|
||||
translated = getStrList(section, key + "[" + lang + "]");
|
||||
if (translated.size() > 0)
|
||||
return translated;
|
||||
}
|
||||
|
||||
//fallback to default key
|
||||
return getStrList(section, key);
|
||||
}
|
||||
|
||||
// 修改keyfile内容
|
||||
void KeyFile::setKey(const std::string §ion, const std::string &key, const std::string &value)
|
||||
{
|
||||
if (mainKeyMap.find(section) == mainKeyMap.end())
|
||||
mainKeyMap.insert({section, KeyMap()});
|
||||
|
||||
mainKeyMap[section].insert({key, value});
|
||||
}
|
||||
|
||||
// 写入文件
|
||||
bool KeyFile::saveToFile(const std::string &filePath)
|
||||
{
|
||||
FILE *sfp = fopen(filePath.data(), "w+");
|
||||
if (!sfp)
|
||||
return false;
|
||||
|
||||
|
||||
for (const auto &im : mainKeyMap) {
|
||||
const auto &keyMap = im.second;
|
||||
std::string section = "[" + im.first + "]\n";
|
||||
fputs(section.c_str(), sfp);
|
||||
for (const auto &ik : keyMap) {
|
||||
std::string kv = ik.first + "=" + ik.second + "\n";
|
||||
fputs(kv.c_str(), sfp);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(sfp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyFile::loadFile(const std::string &filePath)
|
||||
{
|
||||
mainKeyMap.clear();
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
}
|
||||
|
||||
std::string lastSection;
|
||||
fp = fopen(filePath.data(), "r");
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
char line[MAX_LINE_LEN] = {0};
|
||||
while (fgets(line, MAX_LINE_LEN, fp)) {
|
||||
char *start = &line[0];
|
||||
char *end = start;
|
||||
while (!strneq(end, "\0", 1))
|
||||
end++;
|
||||
|
||||
end--; // 返回'\0'前一个字符
|
||||
|
||||
// 移除行首
|
||||
while (strneq(start, " ", 1) || strneq(start, "\t", 1))
|
||||
start++;
|
||||
|
||||
// 过滤注释行
|
||||
if (strneq(start, "#", 1))
|
||||
continue;
|
||||
|
||||
// 移除行尾
|
||||
while (strneq(end, "\n", 1) || strneq(end, "\r", 1)
|
||||
|| strneq(end, " ", 1) || strneq(end, "\t", 1))
|
||||
end--;
|
||||
|
||||
char *lPos = strchr(start, '[');
|
||||
char *rPos = strchr(start, ']');
|
||||
if (lPos && rPos && rPos - lPos > 0 && lPos == start && rPos == end) {
|
||||
// 主键
|
||||
std::string section(lPos + 1, size_t(rPos - lPos - 1));
|
||||
mainKeyMap.insert({section, KeyMap()});
|
||||
lastSection = section;
|
||||
} else {
|
||||
char *equal = strchr(start, '=');
|
||||
if (!equal)
|
||||
continue;
|
||||
|
||||
// 文件格式错误
|
||||
if (lastSection.empty()) {
|
||||
std::cout << "failed to load file " << filePath << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 子键
|
||||
std::string key(start, size_t(equal - start));
|
||||
std::string value(equal + 1, size_t(end - equal));
|
||||
for (auto &iter : mainKeyMap) {
|
||||
if (iter.first != lastSection)
|
||||
continue;
|
||||
|
||||
iter.second[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> KeyFile::getMainKeys()
|
||||
{
|
||||
std::vector<std::string> mainKeys;
|
||||
for (const auto &iter : mainKeyMap)
|
||||
mainKeys.push_back(iter.first);
|
||||
|
||||
return mainKeys;
|
||||
}
|
||||
|
||||
void KeyFile::print()
|
||||
{
|
||||
std::cout << "sectionMap: " << std::endl;
|
||||
for (auto sectionMap : mainKeyMap) {
|
||||
std::cout << "section=" << sectionMap.first << std::endl;
|
||||
KeyMap keyMap = sectionMap.second;
|
||||
|
||||
for (auto iter : keyMap) {
|
||||
std::cout << iter.first << "=" << iter.second << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
67
src/lib/keyfile.h
Normal file
67
src/lib/keyfile.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEYFILE_H
|
||||
#define KEYFILE_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
typedef std::map<std::string, std::string> KeyMap;
|
||||
typedef std::map<std::string, KeyMap> MainKeyMap;
|
||||
|
||||
// 解析ini、desktop文件类
|
||||
class KeyFile
|
||||
{
|
||||
public:
|
||||
explicit KeyFile(char separtor = ';');
|
||||
~KeyFile();
|
||||
|
||||
bool getBool(const std::string §ion, const std::string &key, bool defaultValue = false);
|
||||
std::vector<bool> getBoolList(const std::string §ion, const std::string &key, bool defaultValue = false);
|
||||
int getInt(const std::string §ion, const std::string &key, int defaultValue = 0);
|
||||
std::vector<int> getIntList(const std::string §ion, const std::string &key, int defaultValue = 0);
|
||||
int64_t getInt64(const std::string §ion, const std::string &key, int64_t defaultValue = 0);
|
||||
float getFloat(const std::string §ion, const std::string &key, float defaultValue = 0);
|
||||
std::string getStr(const std::string §ion, const std::string &key, std::string defaultValue = "");
|
||||
bool containKey(const std::string §ion, const std::string &key);
|
||||
std::string getLocaleStr(const std::string §ion, const std::string &key, std::string defaultLocale = "");
|
||||
std::vector<std::string> getStrList(const std::string §ion, const std::string &key);
|
||||
std::vector<std::string> getLocaleStrList(const std::string §ion, const std::string &key, std::string defaultLocale = "");
|
||||
|
||||
void setKey(const std::string §ion, const std::string &key, const std::string &value);
|
||||
bool saveToFile(const std::string &filePath);
|
||||
bool loadFile(const std::string &filePath);
|
||||
std::vector<std::string> getMainKeys();
|
||||
|
||||
// for test
|
||||
void print();
|
||||
|
||||
private:
|
||||
MainKeyMap mainKeyMap; // section -> key : value
|
||||
std::string filePath;
|
||||
FILE *fp;
|
||||
bool modified;
|
||||
char listSeparator;
|
||||
};
|
||||
|
||||
#endif // KEYFILE_H
|
72
src/lib/lang.h
Normal file
72
src/lib/lang.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LANG_H
|
||||
#define LANG_H
|
||||
|
||||
#include "dstring.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
// 返回用户语言,参见man gettext
|
||||
inline std::vector<std::string> queryLangs() {
|
||||
std::vector<std::string> ret;
|
||||
const char *lcAll = getenv("LC_ALL");
|
||||
const char *lcMessage = getenv("LC_MESSAGE");
|
||||
const char *language = getenv("LANGUAGE");
|
||||
const char *lang = getenv("LANG");
|
||||
|
||||
auto cutOff = [](std::string str)->std::string {
|
||||
size_t idx = str.find(".");
|
||||
if (idx == std::string::npos)
|
||||
return str;
|
||||
|
||||
return std::string(str).substr(0, idx);
|
||||
};
|
||||
|
||||
if (lcAll && std::string(lcAll) != "C"
|
||||
&& language && std::string(language) != "")
|
||||
{
|
||||
std::vector<std::string> splits = DString::splitChars(language, ':');
|
||||
for (const auto &l : splits) {
|
||||
ret.push_back(cutOff(l));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (lcAll && std::string(lcAll) != "")
|
||||
ret.push_back(cutOff(lcAll));
|
||||
|
||||
if (lcMessage && std::string(lcMessage) != "")
|
||||
ret.push_back(cutOff(lcMessage));
|
||||
|
||||
if (lang && std::string(lang) != "")
|
||||
ret.push_back(cutOff(lang));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif // LANG_H
|
72
src/lib/lang.hpp
Normal file
72
src/lib/lang.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LANG_H
|
||||
#define LANG_H
|
||||
|
||||
#include "dstring.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
// 返回用户语言,参见man gettext
|
||||
inline std::vector<std::string> queryLangs() {
|
||||
std::vector<std::string> ret;
|
||||
const char *lcAll = getenv("LC_ALL");
|
||||
const char *lcMessage = getenv("LC_MESSAGE");
|
||||
const char *language = getenv("LANGUAGE");
|
||||
const char *lang = getenv("LANG");
|
||||
|
||||
auto cutOff = [](std::string str)->std::string {
|
||||
size_t idx = str.find(".");
|
||||
if (idx == std::string::npos)
|
||||
return str;
|
||||
|
||||
return std::string(str).substr(0, idx);
|
||||
};
|
||||
|
||||
if (lcAll && std::string(lcAll) != "C"
|
||||
&& language && std::string(language) != "")
|
||||
{
|
||||
std::vector<std::string> splits = DString::splitChars(language, ':');
|
||||
for (const auto &l : splits) {
|
||||
ret.push_back(cutOff(l));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (lcAll && std::string(lcAll) != "")
|
||||
ret.push_back(cutOff(lcAll));
|
||||
|
||||
if (lcMessage && std::string(lcMessage) != "")
|
||||
ret.push_back(cutOff(lcMessage));
|
||||
|
||||
if (lang && std::string(lang) != "")
|
||||
ret.push_back(cutOff(lang));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif // LANG_H
|
31
src/lib/macro.h
Normal file
31
src/lib/macro.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MACRO_H
|
||||
#define MACRO_H
|
||||
|
||||
#define _likely_(x) (__builtin_expect(!!(x), 1))
|
||||
#define _unlikely_(x) (__builtin_expect(!!(x), 0))
|
||||
|
||||
#define MAX_FILEPATH_LEN 256
|
||||
#define MAX_LINE_LEN 256
|
||||
|
||||
#endif // MACRO_H
|
188
src/lib/process.cpp
Normal file
188
src/lib/process.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "process.h"
|
||||
#include "macro.h"
|
||||
#include "dstring.h"
|
||||
#include "dfile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define FILECONTENLEN 2048
|
||||
|
||||
Process::Process()
|
||||
: pid(0)
|
||||
, ppid(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Process::Process(int _pid)
|
||||
: pid(_pid)
|
||||
, ppid(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool Process::isExist()
|
||||
{
|
||||
std::string procDir = "/proc/" + std::to_string(pid);
|
||||
return DFile::isExisted(procDir);
|
||||
}
|
||||
|
||||
std::vector<std::string> Process::getCmdLine()
|
||||
{
|
||||
if (cmdLine.size() == 0) {
|
||||
std::string cmdlineFile = getFile("cmdline");
|
||||
cmdLine = readFile(cmdlineFile);
|
||||
}
|
||||
|
||||
return cmdLine;
|
||||
}
|
||||
|
||||
std::string Process::getCwd()
|
||||
{
|
||||
if (cwd.empty()) {
|
||||
std::string cwdFile = getFile("cwd");
|
||||
char path[MAX_FILEPATH_LEN] = {};
|
||||
ssize_t len = readlink(cwdFile.c_str(), path, MAX_FILEPATH_LEN);
|
||||
if (len > 0 && len < MAX_FILEPATH_LEN) {
|
||||
cwd = std::string(path) + "/";
|
||||
}
|
||||
}
|
||||
|
||||
return cwd;
|
||||
}
|
||||
|
||||
std::string Process::getExe()
|
||||
{
|
||||
if (exe.empty()) {
|
||||
std::string cmdLineFile = getFile("exe");
|
||||
char path[MAX_FILEPATH_LEN] = {};
|
||||
ssize_t len = readlink(cmdLineFile.c_str(), path, MAX_FILEPATH_LEN);
|
||||
if (len > 0 && len < MAX_FILEPATH_LEN) {
|
||||
exe = std::string(path);
|
||||
}
|
||||
}
|
||||
|
||||
return exe;
|
||||
}
|
||||
|
||||
std::vector<std::string> Process::getEnviron()
|
||||
{
|
||||
if (environ.size() == 0) {
|
||||
std::string envFile = getFile("environ");
|
||||
environ = readFile(envFile);
|
||||
}
|
||||
|
||||
return environ;
|
||||
}
|
||||
|
||||
std::string Process::getEnv(const std::string &key)
|
||||
{
|
||||
if (environ.size() == 0)
|
||||
environ = getEnviron();
|
||||
|
||||
std::string keyPrefix = key + "=";
|
||||
for (auto & env : environ) {
|
||||
if (DString::startWith(env, keyPrefix)) {
|
||||
ulong len = keyPrefix.size();
|
||||
return env.substr(len, env.size() - len);
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
Status Process::getStatus()
|
||||
{
|
||||
if (status.size() == 0) {
|
||||
std::string statusFile = getFile("status");
|
||||
FILE *fp = fopen(statusFile.c_str(), "r");
|
||||
if (!fp)
|
||||
return status;
|
||||
|
||||
char line[MAX_LINE_LEN] = {0};
|
||||
while (fgets(line, MAX_LINE_LEN, fp)) {
|
||||
std::string info(line);
|
||||
std::vector<std::string> parts = DString::splitStr(info, ':');
|
||||
if (parts.size() == 2)
|
||||
status[parts[0]] = parts[1];
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
std::vector<int> Process::getUids()
|
||||
{
|
||||
if (uids.size() == 0) {
|
||||
if (status.find("Uid") != status.end()) {
|
||||
std::string uidGroup = status["Uid"];
|
||||
std::vector<std::string> parts = DString::splitStr(uidGroup, '\t');
|
||||
uids.reserve(parts.size());
|
||||
std::transform(parts.begin(), parts.end(), uids.begin(),
|
||||
[](std::string idStr) -> int {return std::stoi(idStr);});
|
||||
}
|
||||
}
|
||||
|
||||
return uids;
|
||||
}
|
||||
|
||||
int Process::getPid()
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
|
||||
int Process::getPpid()
|
||||
{
|
||||
if (ppid == 0) {
|
||||
if (status.find("PPid") != status.end()) {
|
||||
ppid = std::stoi(status["PPid"]);
|
||||
}
|
||||
}
|
||||
|
||||
return ppid;
|
||||
}
|
||||
|
||||
std::string Process::getFile(const std::string &name)
|
||||
{
|
||||
return "/proc/" + std::to_string(pid) + "/" + name;
|
||||
}
|
||||
|
||||
// /proc is not real file system
|
||||
std::vector<std::string> Process::readFile(std::string fileName)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
std::FILE *fp = std::fopen(fileName.c_str(), "r");
|
||||
if (!fp)
|
||||
return ret;
|
||||
|
||||
std::vector<char> content(FILECONTENLEN);
|
||||
std::size_t len = std::fread(&content[0], 1, FILECONTENLEN, fp);
|
||||
std::fclose(fp);
|
||||
|
||||
ret = DString::splitVectorChars(content, len, '\0');
|
||||
return ret;
|
||||
}
|
62
src/lib/process.h
Normal file
62
src/lib/process.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_H
|
||||
#define PROCESS_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
typedef std::map<std::string, std::string> Status;
|
||||
|
||||
class Process
|
||||
{
|
||||
public:
|
||||
Process();
|
||||
explicit Process(int _pid);
|
||||
|
||||
bool isExist();
|
||||
std::vector<std::string> getCmdLine();
|
||||
std::string getCwd();
|
||||
std::string getExe();
|
||||
std::vector<std::string> getEnviron();
|
||||
std::string getEnv(const std::string &key);
|
||||
Status getStatus();
|
||||
std::vector<int> getUids();
|
||||
int getPid();
|
||||
int getPpid();
|
||||
|
||||
private:
|
||||
std::string getFile(const std::string &name);
|
||||
std::vector<std::string> readFile(std::string fileName);
|
||||
|
||||
int pid;
|
||||
std::vector<std::string> cmdLine;
|
||||
std::string cwd;
|
||||
std::string exe;
|
||||
std::vector<std::string> environ;
|
||||
Status status;
|
||||
std::vector<int> uids;
|
||||
int ppid;
|
||||
};
|
||||
|
||||
#endif // PROCESS_H
|
574
src/lib/xcbutils.cpp
Normal file
574
src/lib/xcbutils.cpp
Normal file
@ -0,0 +1,574 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "xcbutils.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
XCBUtils::XCBUtils()
|
||||
{
|
||||
connect = xcb_connect(nullptr, &screenNum); // nullptr表示默认使用环境变量$DISPLAY获取屏幕
|
||||
if (xcb_connection_has_error(connect)) {
|
||||
std::cout << "XCBUtils: init xcb_connect error" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xcb_ewmh_init_atoms_replies(&ewmh,
|
||||
xcb_ewmh_init_atoms(connect, &ewmh), // 初始化Atom
|
||||
nullptr))
|
||||
std::cout << "XCBUtils: init ewmh error" << std::endl;
|
||||
}
|
||||
|
||||
XCBUtils::~XCBUtils()
|
||||
{
|
||||
if (connect) {
|
||||
xcb_disconnect(connect); // 关闭连接并释放
|
||||
connect = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
XWindow XCBUtils::allocId()
|
||||
{
|
||||
return xcb_generate_id(connect);
|
||||
}
|
||||
|
||||
void XCBUtils::killClientChecked(XWindow xid)
|
||||
{
|
||||
xcb_kill_client_checked(connect, xid);
|
||||
}
|
||||
|
||||
xcb_get_property_reply_t *XCBUtils::getPropertyValueReply(XWindow xid, XCBAtom property, XCBAtom type)
|
||||
{
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property(connect,
|
||||
0,
|
||||
xid,
|
||||
property,
|
||||
type,
|
||||
0,
|
||||
MAXLEN);
|
||||
return xcb_get_property_reply(connect, cookie, nullptr);
|
||||
}
|
||||
|
||||
void *XCBUtils::getPropertyValue(XWindow xid, XCBAtom property, XCBAtom type)
|
||||
{
|
||||
void *value = nullptr;
|
||||
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, property, type);
|
||||
if (reply) {
|
||||
if (xcb_get_property_value_length(reply) > 0) {
|
||||
value = xcb_get_property_value(reply);
|
||||
}
|
||||
free(reply);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string XCBUtils::getUTF8PropertyStr(XWindow xid, XCBAtom property)
|
||||
{
|
||||
std::string ret;
|
||||
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, property, ewmh.UTF8_STRING);
|
||||
if (reply) {
|
||||
ret = getUTF8StrFromReply(reply);
|
||||
|
||||
free(reply);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
XCBAtom XCBUtils::getAtom(const char *name)
|
||||
{
|
||||
XCBAtom ret = atomCache.getVal(name);
|
||||
if (ret == ATOMNONE) {
|
||||
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connect, false, strlen(name), name);
|
||||
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply (connect,
|
||||
cookie,
|
||||
nullptr);
|
||||
if (reply) {
|
||||
atomCache.store(name, reply->atom);
|
||||
ret = reply->atom;
|
||||
|
||||
free(reply);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string XCBUtils::getAtomName(XCBAtom atom)
|
||||
{
|
||||
std::string ret = atomCache.getName(atom);
|
||||
if (ret.empty()) {
|
||||
xcb_get_atom_name_cookie_t cookie = xcb_get_atom_name(connect, atom);
|
||||
xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(connect,
|
||||
cookie,
|
||||
nullptr);
|
||||
if (reply) {
|
||||
char *name = xcb_get_atom_name_name(reply);
|
||||
if (name) {
|
||||
atomCache.store(name, atom);
|
||||
ret = name;
|
||||
}
|
||||
|
||||
free(reply);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Geometry XCBUtils::getWindowGeometry(XWindow xid)
|
||||
{
|
||||
Geometry ret;
|
||||
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(connect, xid);
|
||||
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(connect, cookie, nullptr);
|
||||
if (reply) {
|
||||
ret.x = reply->x;
|
||||
ret.y = reply->y;
|
||||
ret.width = reply->width;
|
||||
ret.height = reply->height;
|
||||
|
||||
free(reply);
|
||||
} else {
|
||||
std::cout << xid << " getWindowGeometry err" << std::endl;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
XWindow XCBUtils::getActiveWindow()
|
||||
{
|
||||
XWindow ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_active_window(&ewmh, screenNum);
|
||||
if (!xcb_ewmh_get_active_window_reply(&ewmh, cookie, &ret, nullptr))
|
||||
std::cout << "getActiveWindow error" << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void XCBUtils::setActiveWindow(XWindow xid)
|
||||
{
|
||||
xcb_ewmh_set_active_window(&ewmh, screenNum, xid);
|
||||
}
|
||||
|
||||
std::list<XWindow> XCBUtils::getClientList()
|
||||
{
|
||||
std::list<XWindow> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list(&ewmh, screenNum);
|
||||
xcb_ewmh_get_windows_reply_t reply;
|
||||
if (!xcb_ewmh_get_client_list_reply(&ewmh, cookie, &reply, nullptr))
|
||||
std::cout << "getClientList error" << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < reply.windows_len; i++)
|
||||
ret.push_back(reply.windows[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::list<XWindow> XCBUtils::getClientListStacking()
|
||||
{
|
||||
std::list<XWindow> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_client_list_stacking(&ewmh, screenNum);
|
||||
xcb_ewmh_get_windows_reply_t reply;
|
||||
if (!xcb_ewmh_get_client_list_stacking_reply(&ewmh, cookie, &reply, nullptr))
|
||||
std::cout << "getClientListStacking error" << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < reply.windows_len; i++)
|
||||
ret.push_back(reply.windows[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<XCBAtom> XCBUtils::getWMState(XWindow xid)
|
||||
{
|
||||
std::vector<XCBAtom> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_state(&ewmh, xid);
|
||||
xcb_ewmh_get_atoms_reply_t reply; // a list of Atom
|
||||
if (xcb_ewmh_get_wm_state_reply(&ewmh, cookie, &reply, nullptr)) {
|
||||
for (uint32_t i = 0; i < reply.atoms_len; i++) {
|
||||
ret.push_back(reply.atoms[i]);
|
||||
}
|
||||
} else {
|
||||
std::cout << xid << " getWMState error" << std::endl;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<XCBAtom> XCBUtils::getWMWindoType(XWindow xid)
|
||||
{
|
||||
std::vector<XCBAtom> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type(&ewmh, xid);
|
||||
xcb_ewmh_get_atoms_reply_t reply; // a list of Atom
|
||||
if (!xcb_ewmh_get_wm_window_type_reply(&ewmh, cookie, &reply, nullptr))
|
||||
std::cout << xid << " getWMWindoType error" << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<XCBAtom> XCBUtils::getWMAllowedActions(XWindow xid)
|
||||
{
|
||||
std::vector<XCBAtom> ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_allowed_actions(&ewmh, xid);
|
||||
xcb_ewmh_get_atoms_reply_t reply; // a list of Atoms
|
||||
if (!xcb_ewmh_get_wm_allowed_actions_reply(&ewmh, cookie, &reply, nullptr))
|
||||
std::cout << xid << " getWMAllowedActions error" << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < reply.atoms_len; i++) {
|
||||
ret.push_back(reply.atoms[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void XCBUtils::setWMAllowedActions(XWindow xid, std::vector<XCBAtom> actions)
|
||||
{
|
||||
XCBAtom list[MAXALLOWEDACTIONLEN] {0};
|
||||
for (size_t i = 0; i < actions.size(); i++)
|
||||
list[i] = actions[i];
|
||||
|
||||
xcb_ewmh_set_wm_allowed_actions(&ewmh, xid, actions.size(), list);
|
||||
}
|
||||
|
||||
std::string XCBUtils::getWMName(XWindow xid)
|
||||
{
|
||||
std::string ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name(&ewmh, xid);
|
||||
xcb_ewmh_get_utf8_strings_reply_t reply1;
|
||||
if (!xcb_ewmh_get_wm_name_reply(&ewmh, cookie, &reply1, nullptr))
|
||||
std::cout << xid << " getWMName error" << std::endl;
|
||||
|
||||
ret.assign(reply1.strings);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t XCBUtils::getWMPid(XWindow xid)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_pid(&ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_pid_reply(&ewmh, cookie, &ret, nullptr))
|
||||
std::cout << xid << " getWMPid error" << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string XCBUtils::getWMIconName(XWindow xid)
|
||||
{
|
||||
std::string ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_name(&ewmh, xid);
|
||||
xcb_ewmh_get_utf8_strings_reply_t reply;
|
||||
if (!xcb_ewmh_get_wm_icon_name_reply(&ewmh, cookie, &reply, nullptr))
|
||||
std::cout << xid << " getWMIconName error" << std::endl;
|
||||
|
||||
ret.assign(reply.strings);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<WMIcon> XCBUtils::getWMIcon(XWindow xid)
|
||||
{
|
||||
std::vector<WMIcon> ret;
|
||||
/*
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon(&ewmh, xid);
|
||||
xcb_ewmh_get_wm_icon_reply_t reply;
|
||||
if (xcb_ewmh_get_wm_icon_reply(&ewmh, cookie, &reply, nullptr)) {
|
||||
xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&reply);
|
||||
auto fcn = [](xcb_ewmh_wm_icon_iterator_t it) {
|
||||
std::vector<BYTE> data;
|
||||
uint32_t *dat = it.data;
|
||||
int area = it.width * it.height;
|
||||
for (int i = 0; i < (2 + area) * 4; i++, dat++) { // TODO check data accuracy
|
||||
data.push_back(*dat);
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
ret.push_back({iter.width, iter.height, fcn(iter)});
|
||||
|
||||
while (iter.rem >= 1) {
|
||||
xcb_ewmh_get_wm_icon_next(&iter);
|
||||
ret.push_back({iter.width, iter.height, fcn(iter)});
|
||||
}
|
||||
|
||||
xcb_ewmh_get_wm_icon_reply_wipe(&reply); // clear
|
||||
}
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
XWindow XCBUtils::getWMClientLeader(XWindow xid)
|
||||
{
|
||||
XWindow ret;
|
||||
XCBAtom atom = getAtom("WM_CLIENT_LEADER");
|
||||
void *value = getPropertyValue(xid, atom, XCB_ATOM_INTEGER);
|
||||
std::cout << "getWMClientLeader:" << (char*)value << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void XCBUtils::requestCloseWindow(XWindow xid, uint32_t timestamp)
|
||||
{
|
||||
xcb_ewmh_request_close_window(&ewmh, screenNum, xid, timestamp, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER);
|
||||
}
|
||||
|
||||
uint32_t XCBUtils::getWMDesktop(XWindow xid)
|
||||
{
|
||||
uint32_t ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_desktop(&ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_desktop_reply(&ewmh, cookie, &ret, nullptr))
|
||||
std::cout << xid << " getWMDesktop error" << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void XCBUtils::setWMDesktop(XWindow xid, uint32_t desktop)
|
||||
{
|
||||
xcb_ewmh_set_wm_desktop(&ewmh, xid, desktop);
|
||||
}
|
||||
|
||||
void XCBUtils::setCurrentWMDesktop(uint32_t desktop)
|
||||
{
|
||||
xcb_ewmh_set_current_desktop(&ewmh, screenNum, desktop);
|
||||
}
|
||||
|
||||
uint32_t XCBUtils::getCurrentWMDesktop()
|
||||
{
|
||||
uint32_t ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop(&ewmh, screenNum);
|
||||
if (!xcb_ewmh_get_current_desktop_reply(&ewmh, cookie, &ret, nullptr))
|
||||
std::cout << "getCurrentWMDesktop error" << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool XCBUtils::isGoodWindow(XWindow xid)
|
||||
{
|
||||
bool ret = false;
|
||||
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(connect, xid);
|
||||
xcb_generic_error_t **errStore = nullptr;
|
||||
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(connect, cookie, errStore);
|
||||
if (reply) {
|
||||
if (!errStore) // 正常获取窗口geometry则判定为good
|
||||
ret = true;
|
||||
|
||||
free(reply);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO XCB下无_MOTIF_WM_HINTS属性
|
||||
MotifWMHints XCBUtils::getWindowMotifWMHints(XWindow xid)
|
||||
{
|
||||
MotifWMHints ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool XCBUtils::hasXEmbedInfo(XWindow xid)
|
||||
{
|
||||
//XCBAtom atom = getAtom("_XEMBED_INFO");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
XWindow XCBUtils::getWMTransientFor(XWindow xid)
|
||||
{
|
||||
XWindow ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_transient_for(connect, xid);
|
||||
if (!xcb_icccm_get_wm_transient_for_reply(connect, cookie, &ret, nullptr))
|
||||
std::cout << xid << " getWMTransientFor error" << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t XCBUtils::getWMUserTime(XWindow xid)
|
||||
{
|
||||
uint32_t ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_user_time(&ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_user_time_reply(&ewmh, cookie, &ret, nullptr))
|
||||
std::cout << xid << " getWMUserTime error" << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int XCBUtils::getWMUserTimeWindow(XWindow xid)
|
||||
{
|
||||
XCBAtom ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_user_time_window(&ewmh, xid);
|
||||
if (!xcb_ewmh_get_wm_user_time_window_reply(&ewmh, cookie, &ret, NULL))
|
||||
std::cout << xid << " getWMUserTimeWindow error" << std::endl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WMClass XCBUtils::getWMClass(XWindow xid)
|
||||
{
|
||||
WMClass ret;
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_class(connect, xid);
|
||||
xcb_icccm_get_wm_class_reply_t reply;
|
||||
if (!xcb_icccm_get_wm_class_reply(connect, cookie, &reply, nullptr)) {
|
||||
if (reply.class_name)
|
||||
ret.className.assign(reply.class_name);
|
||||
|
||||
if (reply.instance_name)
|
||||
ret.instanceName.assign(reply.instance_name);
|
||||
|
||||
//xcb_icccm_get_wm_class_reply_wipe(&reply);
|
||||
} else {
|
||||
std::cout << xid << " getWMClass error" << std::endl;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO
|
||||
void XCBUtils::minimizeWindow(XWindow xid)
|
||||
{
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints(connect, xid);
|
||||
xcb_icccm_wm_hints_t *hints = new xcb_icccm_wm_hints_t; // 分配堆空间
|
||||
xcb_icccm_get_wm_hints_reply(connect, cookie, hints, nullptr);
|
||||
xcb_icccm_wm_hints_set_iconic(hints);
|
||||
xcb_icccm_set_wm_hints(connect, xid, hints);
|
||||
free(hints);
|
||||
}
|
||||
|
||||
void XCBUtils::maxmizeWindow(XWindow xid)
|
||||
{
|
||||
xcb_ewmh_request_change_wm_state(&ewmh
|
||||
, screenNum
|
||||
, xid
|
||||
, XCB_EWMH_WM_STATE_ADD
|
||||
, getAtom("_NET_WM_STATE_MAXIMIZED_VERT")
|
||||
, getAtom("_NET_WM_STATE_MAXIMIZED_HORZ")
|
||||
, XCB_EWMH_CLIENT_SOURCE_TYPE_OTHER);
|
||||
}
|
||||
|
||||
// TODO
|
||||
std::vector<std::string> XCBUtils::getWMCommand(XWindow xid)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
xcb_get_property_reply_t *reply = getPropertyValueReply(xid, XCB_ATOM_WM_COMMAND, ewmh.UTF8_STRING);
|
||||
if (reply) {
|
||||
ret = getUTF8StrsFromReply(reply);
|
||||
free(reply);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string XCBUtils::getUTF8StrFromReply(xcb_get_property_reply_t *reply)
|
||||
{
|
||||
std::string ret;
|
||||
if (!reply || reply->format != 8)
|
||||
return ret;
|
||||
|
||||
char data[12] = {0};
|
||||
for (uint32_t i=0; i < reply->value_len; i++) {
|
||||
data[i] = char(reply->pad0[i]);
|
||||
}
|
||||
ret.assign(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> XCBUtils::getUTF8StrsFromReply(xcb_get_property_reply_t *reply)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
if (!reply)
|
||||
return ret;
|
||||
|
||||
if (reply->format != 8)
|
||||
return ret;
|
||||
|
||||
|
||||
// 字符串拆分
|
||||
uint32_t start = 0;
|
||||
for (uint32_t i=0; i < reply->value_len; i++) {
|
||||
if (reply->pad0[i] == 0) {
|
||||
char data[12] = {0};
|
||||
int count = 0;
|
||||
for (uint32_t j=start; j < i; j++)
|
||||
data[count++] = char(reply->pad0[j]);
|
||||
|
||||
data[count] = 0;
|
||||
ret.push_back(data);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
XWindow XCBUtils::getRootWindow()
|
||||
{
|
||||
XWindow rootWindow = 0;
|
||||
/* Get the first screen */
|
||||
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connect)).data;
|
||||
if (screen)
|
||||
rootWindow = screen->root;
|
||||
|
||||
std::cout << "getRootWinodw: " << rootWindow << std::endl;
|
||||
return rootWindow;
|
||||
}
|
||||
|
||||
void XCBUtils::registerEvents(XWindow xid, uint32_t eventMask)
|
||||
{
|
||||
uint32_t value[1] = {eventMask};
|
||||
xcb_void_cookie_t cookie = xcb_change_window_attributes_checked(connect,
|
||||
xid,
|
||||
XCB_CW_EVENT_MASK,
|
||||
&value);
|
||||
xcb_flush(connect);
|
||||
|
||||
xcb_generic_error_t *error = xcb_request_check(connect, cookie);
|
||||
if (error != nullptr) {
|
||||
std::cout << "window " << xid << "registerEvents error" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AtomCache::AtomCache()
|
||||
{
|
||||
}
|
||||
|
||||
XCBAtom AtomCache::getVal(std::string name)
|
||||
{
|
||||
XCBAtom atom = ATOMNONE;
|
||||
auto search = atoms.find(name);
|
||||
if (search != atoms.end())
|
||||
atom = search->second;
|
||||
|
||||
return atom;
|
||||
}
|
||||
|
||||
std::string AtomCache::getName(XCBAtom atom)
|
||||
{
|
||||
std::string ret;
|
||||
auto search = atomNames.find(atom);
|
||||
if (search != atomNames.end())
|
||||
ret = search->second;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AtomCache::store(std::string name, XCBAtom value)
|
||||
{
|
||||
atoms[name] = value;
|
||||
atomNames[value] = name;
|
||||
}
|
272
src/lib/xcbutils.h
Normal file
272
src/lib/xcbutils.h
Normal file
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XCBUTILS_H
|
||||
#define XCBUTILS_H
|
||||
|
||||
#include <xcb/xproto.h>
|
||||
#include <xcb/xcb_ewmh.h>
|
||||
#include <xcb/xcb_icccm.h>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#define MAXLEN 0xffff
|
||||
#define MAXALLOWEDACTIONLEN 256
|
||||
#define ATOMNONE 0
|
||||
|
||||
typedef xcb_window_t XWindow ;
|
||||
typedef xcb_atom_t XCBAtom;
|
||||
typedef xcb_destroy_notify_event_t DestroyEvent;
|
||||
typedef xcb_map_notify_event_t MapEvent;
|
||||
typedef xcb_configure_notify_event_t ConfigureEvent;
|
||||
typedef xcb_property_notify_event_t PropertyEvent;
|
||||
typedef xcb_event_mask_t EventMask;
|
||||
typedef struct {
|
||||
std::string instanceName;
|
||||
std::string className;
|
||||
} WMClass;
|
||||
|
||||
typedef struct {
|
||||
int16_t x, y;
|
||||
uint16_t width, height;
|
||||
} Geometry;
|
||||
|
||||
typedef struct {
|
||||
uint32_t flags;
|
||||
uint32_t functions;
|
||||
uint32_t decorations;
|
||||
int32_t inputMode;
|
||||
uint32_t status;
|
||||
} MotifWMHints;
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef struct {
|
||||
uint32_t width; /** Icon width */
|
||||
uint32_t height; /** Icon height */
|
||||
std::vector<BYTE> data; /** Rows, left to right and top to bottom of the CARDINAL ARGB */
|
||||
} WMIcon;
|
||||
|
||||
// 缓存atom,减少X访问 TODO 加读写锁
|
||||
class AtomCache {
|
||||
public:
|
||||
AtomCache();
|
||||
|
||||
XCBAtom getVal(std::string name);
|
||||
std::string getName(XCBAtom atom);
|
||||
void store(std::string name, XCBAtom value);
|
||||
|
||||
public:
|
||||
std::map<std::string, XCBAtom> atoms;
|
||||
std::map<XCBAtom, std::string> atomNames;
|
||||
};
|
||||
|
||||
// XCB接口封装, 参考getCurrentWMDesktop
|
||||
class XCBUtils
|
||||
{
|
||||
XCBUtils();
|
||||
XCBUtils(const XCBUtils &other);
|
||||
XCBUtils & operator= (const XCBUtils &other);
|
||||
~XCBUtils();
|
||||
|
||||
public:
|
||||
static XCBUtils *instance() {
|
||||
static XCBUtils instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
// test
|
||||
xcb_connection_t *getConnect() {return connect;}
|
||||
|
||||
/************************* xcb method ***************************/
|
||||
// 分配XID
|
||||
XWindow allocId();
|
||||
|
||||
/************************* xpropto method ***************************/
|
||||
// 杀掉进程
|
||||
void killClientChecked(XWindow xid);
|
||||
|
||||
// 获取属性reply, 返回值必须free
|
||||
xcb_get_property_reply_t *getPropertyValueReply(XWindow xid, XCBAtom property, XCBAtom type = XCB_ATOM_ATOM);
|
||||
|
||||
// 获取属性
|
||||
void *getPropertyValue(XWindow xid, XCBAtom property, XCBAtom type = XCB_ATOM_ATOM);
|
||||
|
||||
// 获取字符串属性
|
||||
std::string getUTF8PropertyStr(XWindow xid, XCBAtom property);
|
||||
|
||||
// 获取名称对应的Atom
|
||||
XCBAtom getAtom(const char *name);
|
||||
|
||||
// 获取Atom对应的名称
|
||||
std::string getAtomName(XCBAtom atom);
|
||||
|
||||
// 获取窗口矩形
|
||||
Geometry getWindowGeometry(XWindow xid);
|
||||
|
||||
// 判断当前窗口是否正常
|
||||
bool isGoodWindow(XWindow xid);
|
||||
|
||||
// 获取窗口
|
||||
MotifWMHints getWindowMotifWMHints(XWindow xid);
|
||||
|
||||
bool hasXEmbedInfo(XWindow xid);
|
||||
|
||||
/************************* ewmh method ***************************/
|
||||
|
||||
// 获取活动窗口 _NET_ACTIVE_WINDOW
|
||||
XWindow getActiveWindow();
|
||||
|
||||
// 设置活动窗口 _NET_ACTIVE_WINDOW
|
||||
void setActiveWindow(XWindow xid);
|
||||
|
||||
// 获取窗口列表 _NET_CLIENT_LIST
|
||||
std::list<XWindow> getClientList();
|
||||
|
||||
// 获取窗口列表 _NET_CLIENT_LIST_STACKING
|
||||
std::list<XWindow> getClientListStacking();
|
||||
|
||||
// 获取窗口状态 _NET_WM_STATE
|
||||
/*
|
||||
_NET_WM_STATE_MODAL, ATOM
|
||||
_NET_WM_STATE_STICKY, ATOM
|
||||
_NET_WM_STATE_MAXIMIZED_VERT, ATOM
|
||||
_NET_WM_STATE_MAXIMIZED_HORZ, ATOM
|
||||
_NET_WM_STATE_SHADED, ATOM
|
||||
_NET_WM_STATE_SKIP_TASKBAR, ATOM
|
||||
_NET_WM_STATE_SKIP_PAGER, ATOM
|
||||
_NET_WM_STATE_HIDDEN, ATOM
|
||||
_NET_WM_STATE_FULLSCREEN, ATOM
|
||||
_NET_WM_STATE_ABOVE, ATOM
|
||||
_NET_WM_STATE_BELOW, ATOM
|
||||
_NET_WM_STATE_DEMANDS_ATTENTION, ATOM
|
||||
*/
|
||||
std::vector<XCBAtom> getWMState(XWindow xid);
|
||||
|
||||
// 获取窗口类型 _NET_WM_WINDOW_TYPE
|
||||
// Rationale: This hint is intended to replace the MOTIF hints.
|
||||
// One of the objections to the MOTIF hints is that they are a purely visual description of the window decoration.
|
||||
// By describing the function of the window, the Window Manager can apply consistent decoration and behavior to windows of the same type.
|
||||
// Possible examples of behavior include keeping dock/panels on top or allowing pinnable menus / toolbars to only be hidden
|
||||
// when another window has focus
|
||||
/*
|
||||
_NET_WM_WINDOW_TYPE_DESKTOP, ATOM
|
||||
_NET_WM_WINDOW_TYPE_DOCK, ATOM
|
||||
_NET_WM_WINDOW_TYPE_TOOLBAR, ATOM
|
||||
_NET_WM_WINDOW_TYPE_MENU, ATOM
|
||||
_NET_WM_WINDOW_TYPE_UTILITY, ATOM
|
||||
_NET_WM_WINDOW_TYPE_SPLASH, ATOM
|
||||
_NET_WM_WINDOW_TYPE_DIALOG, ATOM
|
||||
_NET_WM_WINDOW_TYPE_DROPDOWN_MENU, ATOM
|
||||
_NET_WM_WINDOW_TYPE_POPUP_MENU, ATOM
|
||||
_NET_WM_WINDOW_TYPE_TOOLTIP, ATOM
|
||||
_NET_WM_WINDOW_TYPE_NOTIFICATION, ATOM
|
||||
_NET_WM_WINDOW_TYPE_COMBO, ATOM
|
||||
_NET_WM_WINDOW_TYPE_DND, ATOM
|
||||
_NET_WM_WINDOW_TYPE_NORMAL, ATOM
|
||||
* */
|
||||
std::vector<XCBAtom> getWMWindoType(XWindow xid);
|
||||
|
||||
// 获取窗口许可动作 _NET_WM_ALLOWED_ACTIONS
|
||||
std::vector<XCBAtom> getWMAllowedActions(XWindow xid);
|
||||
|
||||
// 设置窗口许可动作
|
||||
void setWMAllowedActions(XWindow xid, std::vector<XCBAtom> actions);
|
||||
|
||||
// 获取窗口名称 _NET_WM_NAME
|
||||
std::string getWMName(XWindow xid);
|
||||
|
||||
// 获取窗口所属进程 _NET_WM_PID
|
||||
uint32_t getWMPid(XWindow xid);
|
||||
|
||||
// 获取窗口图标 _NET_WM_ICON_NAME
|
||||
std::string getWMIconName(XWindow xid);
|
||||
|
||||
// _NET_WM_ICON
|
||||
std::vector<WMIcon> getWMIcon(XWindow xid);
|
||||
|
||||
// WM_CLIENT_LEADER
|
||||
XWindow getWMClientLeader(XWindow xid);
|
||||
|
||||
// 关闭窗口 _NET_CLOSE_WINDOW
|
||||
void requestCloseWindow(XWindow xid, uint32_t timestamp);
|
||||
|
||||
// 获取窗口对应桌面 _NET_WM_DESKTOP
|
||||
uint32_t getWMDesktop(XWindow xid);
|
||||
|
||||
// 设置窗口当前桌面
|
||||
void setWMDesktop(XWindow xid, uint32_t desktop);
|
||||
|
||||
// 设置桌面
|
||||
void setCurrentWMDesktop(uint32_t desktop);
|
||||
|
||||
// 获取当前桌面 _NET_CURRENT_DESKTOP
|
||||
uint32_t getCurrentWMDesktop();
|
||||
|
||||
|
||||
/************************* icccm method ***************************/
|
||||
// The WM_TRANSIENT_FOR hint of the ICCCM allows clients to specify that a toplevel window may be closed before the client finishes.
|
||||
// A typical example of a transient window is a dialog.
|
||||
// Some dialogs can be open for a long time, while the user continues to work in the main window.
|
||||
// Other dialogs have to be closed before the user can continue to work in the main window
|
||||
XWindow getWMTransientFor(XWindow xid);
|
||||
|
||||
uint32_t getWMUserTime(XWindow xid);
|
||||
|
||||
int getWMUserTimeWindow(XWindow xid);
|
||||
|
||||
// 获取窗口类型
|
||||
WMClass getWMClass(XWindow xid);
|
||||
|
||||
// 最小化窗口
|
||||
void minimizeWindow(XWindow xid);
|
||||
|
||||
// 最大化窗口
|
||||
void maxmizeWindow(XWindow xid);
|
||||
|
||||
/************************* other method ***************************/
|
||||
// 获取窗口command
|
||||
std::vector<std::string> getWMCommand(XWindow xid);
|
||||
|
||||
// 解析属性为UTF8格式字符串
|
||||
std::string getUTF8StrFromReply(xcb_get_property_reply_t *reply);
|
||||
|
||||
// 解析属性为UTF8格式字符串字符数组
|
||||
std::vector<std::string> getUTF8StrsFromReply(xcb_get_property_reply_t *reply);
|
||||
|
||||
// 获取根窗口
|
||||
XWindow getRootWindow();
|
||||
|
||||
// 注册事件
|
||||
void registerEvents(XWindow xid, uint32_t eventMask);
|
||||
|
||||
|
||||
private:
|
||||
xcb_connection_t *connect;
|
||||
int screenNum;
|
||||
|
||||
xcb_ewmh_connection_t ewmh;
|
||||
AtomCache atomCache; // 和ewmh中Atom类型存在重复部分,扩张了自定义类型
|
||||
};
|
||||
|
||||
#endif // XCBUTILS_H
|
@ -12,7 +12,6 @@ set(SRCS
|
||||
../modules/methods/registe.hpp
|
||||
../modules/util/common.cpp
|
||||
../modules/util/common.h
|
||||
../modules/util/debug
|
||||
../modules/util/filesystem.cpp
|
||||
../modules/util/filesystem.h
|
||||
../modules/util/json.h
|
||||
|
257
src/modules/apps/alrecorder.cpp
Normal file
257
src/modules/apps/alrecorder.cpp
Normal file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "alrecorder.h"
|
||||
#include "dfwatcher.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusError>
|
||||
#include <QtDebug>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
const QString userAppsCfgDir = QDir::homePath() + "/.config/deepin/dde-daemon/apps/";
|
||||
|
||||
AlRecorder::AlRecorder(DFWatcher *_watcher, QObject *parent)
|
||||
: QObject (parent)
|
||||
, watcher(_watcher)
|
||||
, mutex(QMutex(QMutex::NonRecursive))
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
if (!con.registerService("org.deepin.daemon.AlRecorder1"))
|
||||
{
|
||||
qWarning() << "register service AlRecorder1 error:" << con.lastError().message();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!con.registerObject("/org/deepin/daemon/AlRecorder1", this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals))
|
||||
{
|
||||
qWarning() << "register object AlRecorder1 error:" << con.lastError().message();
|
||||
return;
|
||||
}
|
||||
|
||||
connect(watcher, &DFWatcher::Event, this, &AlRecorder::onDFChanged, Qt::QueuedConnection);
|
||||
Q_EMIT ServiceRestarted();
|
||||
}
|
||||
|
||||
AlRecorder::~AlRecorder()
|
||||
{
|
||||
QDBusConnection::sessionBus().unregisterObject("/org/deepin/daemon/AlRecorder1");
|
||||
}
|
||||
|
||||
// 获取未启动应用列表
|
||||
QMap<QString, QStringList> AlRecorder::GetNew()
|
||||
{
|
||||
QMap<QString, QStringList> ret;
|
||||
QMutexLocker locker(&mutex);
|
||||
for (auto is = subRecoders.begin(); is != subRecoders.end(); is++) {
|
||||
QStringList apps;
|
||||
for (auto il = is.value().launchedMap.begin(); il != is.value().launchedMap.end(); il++) {
|
||||
if (!il.value()) // 未启动应用
|
||||
apps.push_back(il.key());
|
||||
}
|
||||
|
||||
if (apps.size() > 0)
|
||||
ret[is.key()] = apps;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 标记应用已启动状态
|
||||
void AlRecorder::MarkLaunched(const QString &filePath)
|
||||
{
|
||||
if (!filePath.endsWith(".desktop"))
|
||||
return;
|
||||
|
||||
QFileInfo info;
|
||||
QMutexLocker locker(&mutex);
|
||||
for (auto sri = subRecoders.begin(); sri != subRecoders.end(); sri++) {
|
||||
if (!filePath.contains(sri.key()))
|
||||
continue;
|
||||
|
||||
info.setFile(filePath);
|
||||
QString name = info.baseName();
|
||||
for (auto li = sri.value().launchedMap.begin(); li != sri.value().launchedMap.end(); li++) {
|
||||
if (li.key() == name && !li.value()) {
|
||||
li.value() = true;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据filePath匹配到唯一应用
|
||||
end:
|
||||
if (info.isDir()) {
|
||||
saveStatusFile(info.absolutePath() + "/");
|
||||
Q_EMIT Launched(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
// 记录Launcher服务卸载应用信息, 终端卸载不会调用该函数, desktopFiles为绝对路径
|
||||
void AlRecorder::UninstallHints(const QStringList &desktopFiles)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
for (auto desktop : desktopFiles) {
|
||||
for (auto sri = subRecoders.begin(); sri != subRecoders.end(); sri++) {
|
||||
if (!desktop.contains(sri.key()))
|
||||
continue;
|
||||
|
||||
QFileInfo info(desktop);
|
||||
sri.value().uninstallMap[info.baseName()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监控目录
|
||||
void AlRecorder::WatchDirs(const QStringList &dataDirs)
|
||||
{
|
||||
for (auto dirPath : dataDirs) {
|
||||
if (subRecoders.contains(dirPath))
|
||||
continue;
|
||||
|
||||
QDir dir(dirPath);
|
||||
QStringList files = dir.entryList(QDir::Files);
|
||||
for (auto &file : files)
|
||||
file = dirPath + file;
|
||||
|
||||
// 监听目录和文件
|
||||
watcher->addDir(dirPath);
|
||||
if (files.size() > 0)
|
||||
watcher->addPaths(files);
|
||||
|
||||
// 初始化对应目录和应用信息
|
||||
initSubRecoder(dirPath);
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化应用目录记录
|
||||
void AlRecorder::initSubRecoder(const QString &dirPath)
|
||||
{
|
||||
subRecorder sub;
|
||||
QByteArray encryText = QCryptographicHash::hash(dirPath.toLatin1(), QCryptographicHash::Md5);
|
||||
QString statusFile = userAppsCfgDir + "launched-" + encryText.toHex() + ".csv";
|
||||
|
||||
// 读取App状态记录
|
||||
QMap<QString, bool> launchedApp;
|
||||
QFile file(statusFile);
|
||||
if (file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
while (!file.atEnd()){
|
||||
QString line(file.readLine());
|
||||
QStringList strs = line.split(",");
|
||||
if (strs.length() != 2)
|
||||
continue;
|
||||
|
||||
if (strs[1].size() > 0 && strs[1][0] == 't')
|
||||
launchedApp[strs[0]] = true;
|
||||
else
|
||||
launchedApp[strs[0]] = false;
|
||||
}
|
||||
file.close();
|
||||
} else {
|
||||
// 读取app desktop
|
||||
QDir dir(dirPath);
|
||||
QStringList files = dir.entryList(QDir::Files);
|
||||
QStringList apps;
|
||||
for (QString file : files) {
|
||||
if (!file.endsWith(".desktop"))
|
||||
continue;
|
||||
|
||||
int index = file.lastIndexOf(".");
|
||||
file.truncate(index);
|
||||
qInfo() << "entry =" << file;
|
||||
apps.push_back(file);
|
||||
}
|
||||
|
||||
// fallback 都打开过
|
||||
for (auto app : apps)
|
||||
launchedApp[app] = true;
|
||||
}
|
||||
|
||||
sub.statusFile = statusFile;
|
||||
sub.launchedMap = launchedApp;
|
||||
subRecoders[dirPath] = sub;
|
||||
}
|
||||
|
||||
void AlRecorder::onDFChanged(const QString &filePath, uint32_t op)
|
||||
{
|
||||
QFileInfo info(filePath);
|
||||
QString dirPath = info.absolutePath() + "/";
|
||||
QString name = info.baseName();
|
||||
subRecorder &sub = subRecoders[dirPath];
|
||||
QMap<QString, bool> &launchedMap = sub.launchedMap;
|
||||
|
||||
// 过滤文件, 仅保留.desktop类型
|
||||
if (!filePath.endsWith(".desktop"))
|
||||
return;
|
||||
|
||||
switch (op) {
|
||||
case DFWatcher::event::Add:
|
||||
qInfo() << "AlRecorder: Add " << filePath;
|
||||
if (!launchedMap.contains(name)) {
|
||||
bool launched = false;
|
||||
if (sub.removedLaunchedMap.find(name) != sub.removedLaunchedMap.end()) {
|
||||
launched = sub.removedLaunchedMap[name];
|
||||
sub.removedLaunchedMap.remove(name);
|
||||
}
|
||||
launchedMap[name] = launched;
|
||||
}
|
||||
sub.uninstallMap.remove(name);
|
||||
saveStatusFile(dirPath); // 刷新状态文件
|
||||
break;
|
||||
case DFWatcher::event::Del:
|
||||
qInfo() << "AlRecorder: Del" << filePath;
|
||||
if (launchedMap.contains(name)) {
|
||||
if (!sub.uninstallMap.contains(name))
|
||||
sub.removedLaunchedMap[name] = launchedMap[name];
|
||||
|
||||
launchedMap.remove(name);
|
||||
}
|
||||
saveStatusFile(dirPath); //刷新状态文件
|
||||
break;
|
||||
case DFWatcher::event::Mod:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AlRecorder::saveStatusFile(const QString &dirPath)
|
||||
{
|
||||
subRecorder sub = subRecoders[dirPath];
|
||||
QString tmpFile = sub.statusFile + "_tmp";
|
||||
QFile fp(tmpFile);
|
||||
bool ok = false;
|
||||
qInfo() << "saveStatusFile=" << dirPath << "create file=" << tmpFile;
|
||||
if (fp.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
||||
QTextStream out(&fp);
|
||||
out << "# " << dirPath << endl;
|
||||
for (auto rl = sub.launchedMap.begin(); rl != sub.launchedMap.end(); rl++) {
|
||||
out << rl.key() << "," << ((rl.value() == true) ? "t" : "f") << endl;
|
||||
}
|
||||
ok = true;
|
||||
fp.close();
|
||||
}
|
||||
|
||||
// 覆盖原文件
|
||||
QFile::remove(sub.statusFile);
|
||||
QFile::rename(tmpFile, sub.statusFile);
|
||||
Q_EMIT StatusSaved(dirPath, sub.statusFile, ok);
|
||||
}
|
||||
|
71
src/modules/apps/alrecorder.h
Normal file
71
src/modules/apps/alrecorder.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ALRECORDER_H
|
||||
#define ALRECORDER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
|
||||
class DFWatcher;
|
||||
|
||||
// 记录应用状态信息
|
||||
class AlRecorder: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.deepin.daemon.AlRecorder1")
|
||||
|
||||
public:
|
||||
struct subRecorder {
|
||||
QString statusFile; // 应用目录状态文件
|
||||
QMap<QString, bool> launchedMap; // 应用启动记录
|
||||
QMap<QString, bool> removedLaunchedMap; // desktop文件卸载记录
|
||||
QMap<QString, bool> uninstallMap; // 记录应用将被卸载状态
|
||||
};
|
||||
|
||||
AlRecorder(DFWatcher *_watcher, QObject *parent = nullptr);
|
||||
~AlRecorder();
|
||||
|
||||
Q_SIGNALS:
|
||||
void Launched(const QString &file);
|
||||
void StatusSaved(const QString &root, const QString &file, bool ok);
|
||||
void ServiceRestarted();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onDFChanged(const QString &filePath, uint32_t op);
|
||||
|
||||
public Q_SLOTS:
|
||||
QMap<QString, QStringList> GetNew();
|
||||
void MarkLaunched(const QString &filePath);
|
||||
void UninstallHints(const QStringList &desktopFiles);
|
||||
void WatchDirs(const QStringList &dataDirs);
|
||||
|
||||
private:
|
||||
void initSubRecoder(const QString &dirPath);
|
||||
void saveStatusFile(const QString &dirPath);
|
||||
|
||||
QMap<QString,subRecorder> subRecoders; // 记录不同应用目录的文件状态
|
||||
DFWatcher *watcher;
|
||||
QMutex mutex;
|
||||
};
|
||||
|
||||
#endif // ALRECODER_H
|
46
src/modules/apps/appmanager.cpp
Normal file
46
src/modules/apps/appmanager.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "appmanager.h"
|
||||
#include "dfwatcher.h"
|
||||
#include "alrecorder.h"
|
||||
#include "basedir.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
|
||||
AppManager::AppManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, watcher(new DFWatcher(this))
|
||||
, recorder(new AlRecorder(watcher, this))
|
||||
{
|
||||
QStringList dataDirs;
|
||||
dataDirs << BaseDir::userAppDir().c_str();
|
||||
for (auto &dir : BaseDir::sysAppDirs())
|
||||
dataDirs << dir.c_str();
|
||||
|
||||
recorder->WatchDirs(dataDirs); // 监控应用desktop
|
||||
}
|
||||
|
||||
AppManager::~AppManager()
|
||||
{
|
||||
|
||||
}
|
41
src/modules/apps/appmanager.h
Normal file
41
src/modules/apps/appmanager.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef APPMANAGER_H
|
||||
#define APPMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class DFWatcher;
|
||||
class AlRecorder;
|
||||
class AppManager: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppManager(QObject *parent = nullptr);
|
||||
~AppManager();
|
||||
|
||||
private:
|
||||
DFWatcher *watcher;
|
||||
AlRecorder *recorder;
|
||||
};
|
||||
|
||||
#endif // APPMANAGER_H
|
132
src/modules/apps/dfwatcher.cpp
Normal file
132
src/modules/apps/dfwatcher.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dfwatcher.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusError>
|
||||
#include <QtDebug>
|
||||
|
||||
const QString dfSuffix = ".desktop";
|
||||
const QString configSuffix = ".json";
|
||||
|
||||
DFWatcher::DFWatcher(QObject *parent)
|
||||
: QObject (parent)
|
||||
, watcher(new QFileSystemWatcher(this))
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
if (!con.registerService("org.deepin.daemon.DFWatcher1"))
|
||||
{
|
||||
qInfo() << "register service app1 error:" << con.lastError().message();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!con.registerObject("/org/deepin/daemon/DFWatcher1", this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals))
|
||||
{
|
||||
qInfo() << "register object DFWatcher error:" << con.lastError().message();
|
||||
return;
|
||||
}
|
||||
|
||||
connect(watcher, &QFileSystemWatcher::fileChanged, this, &DFWatcher::fileUpdated, Qt::QueuedConnection);
|
||||
connect(watcher, &QFileSystemWatcher::directoryChanged, this, &DFWatcher::directoryUpdated, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
DFWatcher::~DFWatcher()
|
||||
{
|
||||
QDBusConnection::sessionBus().unregisterObject("/org/deepin/daemon/DFWatcher1");
|
||||
}
|
||||
|
||||
void DFWatcher::addDir(const QString &path)
|
||||
{
|
||||
// 记录当前目录内容
|
||||
qInfo() << "addDir :" << path;
|
||||
const QDir dir(path);
|
||||
dirContentMap[path] = dir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
|
||||
|
||||
watcher->addPath(path);
|
||||
}
|
||||
|
||||
void DFWatcher::addPaths(const QStringList &paths)
|
||||
{
|
||||
watcher->addPaths(paths);
|
||||
}
|
||||
|
||||
QStringList DFWatcher::files()
|
||||
{
|
||||
return watcher->files();
|
||||
}
|
||||
|
||||
void DFWatcher::removePath(const QString &filepath)
|
||||
{
|
||||
watcher->removePath(filepath);
|
||||
}
|
||||
|
||||
void DFWatcher::fileUpdated(const QString &filePath)
|
||||
{
|
||||
qInfo() << "event: modify filepath=" << filePath;
|
||||
if (filePath.endsWith(dfSuffix) || filePath.endsWith(configSuffix))
|
||||
Q_EMIT Event(filePath, int(event::Mod));
|
||||
}
|
||||
|
||||
void DFWatcher::directoryUpdated(const QString &dirPath)
|
||||
{
|
||||
QStringList recoderedContent = dirContentMap[dirPath];
|
||||
|
||||
const QDir dir(dirPath);
|
||||
QStringList newEntries = dir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
|
||||
|
||||
QSet<QString> newDirSet = QSet<QString>::fromList(newEntries);
|
||||
QSet<QString> currentDirSet = QSet<QString>::fromList(recoderedContent);
|
||||
|
||||
// 添加的文件
|
||||
QSet<QString> newFiles = newDirSet - currentDirSet;
|
||||
QStringList newFile = newFiles.toList();
|
||||
|
||||
// 移除的文件
|
||||
QSet<QString> deletedFiles = currentDirSet - newDirSet;
|
||||
QStringList deleteFile = deletedFiles.toList();
|
||||
|
||||
// 更新目录记录
|
||||
dirContentMap[dirPath] = newEntries;
|
||||
|
||||
// 新增文件
|
||||
if (newFile.size() > 0) {
|
||||
for (auto &file : newFile) {
|
||||
//qInfo() << "event: add filepath=" << file;
|
||||
if (file.endsWith(dfSuffix)) {
|
||||
Q_EMIT Event(dirPath + file, event::Add);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移除文件
|
||||
if (deleteFile.size() > 0) {
|
||||
for (auto &file : deleteFile) {
|
||||
//qInfo() << "event: del filepath=" << file;
|
||||
if (file.endsWith(dfSuffix)) {
|
||||
Q_EMIT Event(dirPath + file, event::Del);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
59
src/modules/apps/dfwatcher.h
Normal file
59
src/modules/apps/dfwatcher.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DFWATCHER_H
|
||||
#define DFWATCHER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QFileSystemWatcher>
|
||||
|
||||
class DFWatcher: public QObject {
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.deepin.daemon.DFWatcher1")
|
||||
|
||||
public:
|
||||
enum event{
|
||||
Add,
|
||||
Del,
|
||||
Mod,
|
||||
};
|
||||
|
||||
explicit DFWatcher(QObject *parent = nullptr);
|
||||
~DFWatcher();
|
||||
|
||||
void addDir(const QString & path);
|
||||
void addPaths(const QStringList &paths);
|
||||
QStringList files();
|
||||
void removePath(const QString &filepath);
|
||||
Q_SIGNALS:
|
||||
void Event(const QString &filepath, int op);
|
||||
|
||||
private Q_SLOTS:
|
||||
void fileUpdated(const QString &filePath);
|
||||
void directoryUpdated(const QString &dirPath);
|
||||
|
||||
private:
|
||||
QFileSystemWatcher *watcher;
|
||||
QMap<QString, QStringList> dirContentMap; // 监控的目录内容列表
|
||||
};
|
||||
|
||||
#endif
|
75
src/modules/dock/appinfo.cpp
Normal file
75
src/modules/dock/appinfo.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "appinfo.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
AppInfo::AppInfo(DesktopInfo &info)
|
||||
: isValid(true)
|
||||
{
|
||||
init(info);
|
||||
}
|
||||
|
||||
AppInfo::AppInfo(const QString &_fileName)
|
||||
: isValid(true)
|
||||
{
|
||||
DesktopInfo info(_fileName.toStdString());
|
||||
init(info);
|
||||
}
|
||||
|
||||
void AppInfo::init(DesktopInfo &info)
|
||||
{
|
||||
if (!info.isValidDesktop()) {
|
||||
isValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string xDeepinVendor= info.kf.getStr(MainSection, "X-Deepin-Vendor");
|
||||
if (xDeepinVendor == "deepin") {
|
||||
name = info.getGenericName().c_str();
|
||||
if (name.isEmpty())
|
||||
name = info.getName().c_str();
|
||||
} else {
|
||||
name = info.getName().c_str();
|
||||
}
|
||||
|
||||
innerId = genInnerIdWithDesktopInfo(info);
|
||||
fileName = info.getFileName().c_str();
|
||||
id = info.getId().c_str();
|
||||
icon = info.getIcon().c_str();
|
||||
installed = info.isInstalled();
|
||||
for (const auto & action : info.getActions()) {
|
||||
actions.push_back(action);
|
||||
}
|
||||
}
|
||||
|
||||
QString AppInfo::genInnerIdWithDesktopInfo(DesktopInfo &info)
|
||||
{
|
||||
std::string cmdline = info.getCommandLine();
|
||||
QByteArray encryText = QCryptographicHash::hash(QString(cmdline.c_str()).toLatin1(), QCryptographicHash::Md5);
|
||||
QString innerId = desktopHashPrefix + encryText.toHex();
|
||||
qInfo() << "app " << info.getId().c_str() << " generate innerId :" << innerId;
|
||||
return innerId;
|
||||
}
|
62
src/modules/dock/appinfo.h
Normal file
62
src/modules/dock/appinfo.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef APPINFO_H
|
||||
#define APPINFO_H
|
||||
|
||||
#include "desktopinfo.h"
|
||||
|
||||
#include<QVector>
|
||||
|
||||
// 应用信息类
|
||||
class AppInfo
|
||||
{
|
||||
public:
|
||||
explicit AppInfo(DesktopInfo &info);
|
||||
explicit AppInfo(const QString &_fileName);
|
||||
|
||||
void init(DesktopInfo &info);
|
||||
QString getFileName() {return fileName;}
|
||||
QString getIcon() {return icon;}
|
||||
QString getId() {return id;}
|
||||
QString getInnerId() {return innerId;}
|
||||
QString getName() {return name;}
|
||||
QVector<DesktopAction> getActions() {return actions;}
|
||||
QString getIdentifyMethod() {return identifyMethod;}
|
||||
void setIdentifyMethod(QString method) {identifyMethod = method;}
|
||||
bool isInstalled() {return installed;}
|
||||
bool isValidApp() {return isValid;}
|
||||
|
||||
private:
|
||||
QString genInnerIdWithDesktopInfo(DesktopInfo &info);
|
||||
|
||||
QString fileName;
|
||||
QString id;
|
||||
QString icon;
|
||||
QString identifyMethod;
|
||||
QString innerId;
|
||||
QString name;
|
||||
QVector<DesktopAction> actions;
|
||||
bool installed;
|
||||
bool isValid;
|
||||
};
|
||||
|
||||
#endif // APPINFO_H
|
91
src/modules/dock/appmenu.cpp
Normal file
91
src/modules/dock/appmenu.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "appmenu.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
AppMenu::AppMenu()
|
||||
: checkableMenu(false)
|
||||
, singleCheck(false)
|
||||
, itemcount(0)
|
||||
, dirty(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// 增加菜单选项
|
||||
void AppMenu::appendItem(AppMenuItem item)
|
||||
{
|
||||
if (!item.text.isEmpty()) {
|
||||
item.id = allocateId();
|
||||
items.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
void AppMenu::handleAction(uint32_t timestamp, QString itemId)
|
||||
{
|
||||
for (auto &item : items) {
|
||||
if (item.id == itemId) {
|
||||
item.action(timestamp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppMenu::setDirtyStatus(bool isDirty)
|
||||
{
|
||||
dirty = isDirty;
|
||||
}
|
||||
|
||||
QString AppMenu::getMenuJsonStr()
|
||||
{
|
||||
QJsonObject obj;
|
||||
QJsonArray array;
|
||||
for (auto item : items) {
|
||||
QJsonObject objItem;
|
||||
objItem["itemId"] = item.id;
|
||||
objItem["itemText"] = item.text;
|
||||
objItem["isActive"] = item.isActive;
|
||||
objItem["isCheckable"] = item.isCheckable;
|
||||
objItem["checked"] = item.checked;
|
||||
objItem["itemIcon"] = item.icon;
|
||||
objItem["itemIconHover"] = item.iconHover;
|
||||
objItem["itemIconInactive"] = item.iconInactive;
|
||||
objItem["showCheckMark"] = item.showCheckMark;
|
||||
objItem["itemSubMenu"] = item.subMenu ? item.subMenu->getMenuJsonStr() : "";
|
||||
array.push_back(QJsonValue(objItem));
|
||||
}
|
||||
obj["items"] = QJsonValue(array);
|
||||
obj["checkableMenu"] = checkableMenu;
|
||||
obj["singleCheck"] = singleCheck;
|
||||
|
||||
QString ret = QJsonDocument(obj).toJson();
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString AppMenu::allocateId()
|
||||
{
|
||||
return QString::number(itemcount++);
|
||||
}
|
||||
|
||||
|
77
src/modules/dock/appmenu.h
Normal file
77
src/modules/dock/appmenu.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef APPMENU_H
|
||||
#define APPMENU_H
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
#include <QVector>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
typedef std::function<void(uint32_t)> AppMenuAction;
|
||||
|
||||
class AppMenu;
|
||||
|
||||
// 应用菜单选项
|
||||
struct AppMenuItem {
|
||||
QString id;
|
||||
QString text;
|
||||
bool isActive;
|
||||
QString isCheckable;
|
||||
QString checked;
|
||||
QString icon;
|
||||
QString iconHover;
|
||||
QString iconInactive;
|
||||
QString showCheckMark;
|
||||
std::shared_ptr<AppMenu> subMenu;
|
||||
|
||||
int hint;
|
||||
AppMenuAction action;
|
||||
};
|
||||
|
||||
|
||||
// 应用菜单类
|
||||
class AppMenu
|
||||
{
|
||||
public:
|
||||
AppMenu();
|
||||
|
||||
void appendItem(AppMenuItem item);
|
||||
void handleAction(uint32_t timestamp, QString itemId);
|
||||
void setDirtyStatus(bool isDirty);
|
||||
QString getMenuJsonStr();
|
||||
|
||||
private:
|
||||
QString allocateId();
|
||||
|
||||
QVector<AppMenuItem> items; // json:"items"
|
||||
bool checkableMenu; // json:"checkableMenu"
|
||||
bool singleCheck; // json:"singleCheck"
|
||||
|
||||
int itemcount;
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
#endif // APPMENU_H
|
103
src/modules/dock/common.h
Normal file
103
src/modules/dock/common.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
#include <QDir>
|
||||
|
||||
const QString configDock = "com.deepin.dde.dock";
|
||||
const QString configAppearance = "com.deepin.dde.appearance";
|
||||
const QString keyHideMode = "Hide_Mode";
|
||||
const QString keyDisplayMode = "Display_Mode";
|
||||
const QString keyPosition = "Position";
|
||||
const QString keyIconSize = "Icon_Size";
|
||||
const QString keyDockedApps = "Docked_Apps";
|
||||
const QString keyShowTimeout = "Show_Timeout";
|
||||
const QString keyHideTimeout = "Hide_Timeout";
|
||||
const QString keyWindowSizeFashion = "Window_Size_Fashion";
|
||||
const QString keyWindowSizeEfficient = "Window_Size_Efficient";
|
||||
const QString keyWinIconPreferredApps = "Win_Icon_Preferred_Apps";
|
||||
const QString keyOpacity = "Opacity";
|
||||
const QString keyPluginSettings = "Plugin_Settings";
|
||||
const QString keyForceQuitApp = "Force_Quit_App";
|
||||
|
||||
const QString scratchDir = QDir::homePath() + "/.local/dock/scratch/";
|
||||
const QMap<QString, QString> pathDirCodeMap {
|
||||
{"/usr/share/applications/", "/S@"},
|
||||
{"/usr/local/share/applications/", "/L@"},
|
||||
{QDir::homePath() + "/.local/share/applications", "/H@"},
|
||||
{QDir::homePath() + "/.local/dock/scratch", "/D@"},
|
||||
};
|
||||
|
||||
const QMap<QString, QString> pathCodeDirMap {
|
||||
{"/S@", "/usr/share/applications/"},
|
||||
{"/L@", "/usr/local/share/applications/"},
|
||||
{"/H@", QDir::homePath() + "/.local/share/applications"},
|
||||
{"/D@", QDir::homePath() + "/.local/dock/scratch"},
|
||||
};
|
||||
|
||||
// DBus服务、路径
|
||||
const QString dbusService = "org.deepin.dde.daemon.Dock1";
|
||||
const QString dbusPath = "/org/deepin/dde/daemon/Dock1";
|
||||
const QString dbusInterface = dbusService;
|
||||
|
||||
const QString windowPatternsFile = "/usr/share/dde/data/window_patterns.json";
|
||||
const QString desktopHashPrefix = "d:";
|
||||
const QString windowHashPrefix = "w:";
|
||||
|
||||
const QString entryDBusObjPathPrefix = dbusPath + "/entries/";
|
||||
const QString entryDBusInterface = dbusInterface + ".Entry";
|
||||
|
||||
// 驻留应用desktop file模板
|
||||
const QString dockedItemTemplate = R"([Desktop Entry]
|
||||
Name=%1
|
||||
Exec=%2
|
||||
Icon=%3
|
||||
Type=Application
|
||||
Terminal=false
|
||||
StartupNotify=false
|
||||
)";
|
||||
|
||||
const QString frontendWindowWmClass = "dde-dock";
|
||||
const int configureNotifyDelay = 100;
|
||||
const int smartHideTimerDelay = 400;
|
||||
|
||||
const int bestIconSize = 48;
|
||||
const int menuItemHintShowAllWindows = 1;
|
||||
|
||||
const int MotifHintFunctions = 1;
|
||||
const int MotifHintDecorations = 2;
|
||||
const int MotifHintInputMode = 4;
|
||||
const int MotifHintStatus = 8;
|
||||
|
||||
const int MotifFunctionNone = 0;
|
||||
const int MotifFunctionAll = 1;
|
||||
const int MotifFunctionResize = 2;
|
||||
const int MotifFunctionMove = 4;
|
||||
const int MotifFunctionMinimize = 8;
|
||||
const int MotifFunctionMaximize = 16;
|
||||
const int MotifFunctionClose = 32;
|
||||
|
||||
const QString ddeLauncherWMClass = "dde-launcher";
|
||||
#endif // COMMON_H
|
229
src/modules/dock/dbusadaptordock.cpp
Normal file
229
src/modules/dock/dbusadaptordock.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dbusadaptordock.h"
|
||||
|
||||
DBusAdaptorDock::DBusAdaptorDock(QObject *parent)
|
||||
: QDBusAbstractAdaptor(parent)
|
||||
{
|
||||
// constructor
|
||||
setAutoRelaySignals(true);
|
||||
|
||||
Dock *dock = static_cast<Dock *>(QObject::parent());
|
||||
if (dock) {
|
||||
connect(dock, &Dock::serviceRestarted, this, [&] {
|
||||
Q_EMIT ServiceRestarted();});
|
||||
connect(dock, &Dock::entryAdded, this, [&](QString entryObjPath, int32_t index){
|
||||
Q_EMIT EntryAdded(QDBusObjectPath(entryObjPath), index);});
|
||||
connect(dock, &Dock::entryRemoved, this, &DBusAdaptorDock::EntryRemoved);
|
||||
connect(dock, &Dock::hideStateChanged, this, &DBusAdaptorDock::HideStateChanged);
|
||||
connect(dock, &Dock::frontendWindowRectChanged, this, &DBusAdaptorDock::FrontendWindowRectChanged);
|
||||
}
|
||||
}
|
||||
|
||||
DBusAdaptorDock::~DBusAdaptorDock()
|
||||
{
|
||||
// destructor
|
||||
}
|
||||
|
||||
int DBusAdaptorDock::displayMode() const
|
||||
{
|
||||
return parent()->getDisplayMode();
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::setDisplayMode(int value)
|
||||
{
|
||||
if (displayMode() != value) {
|
||||
parent()->setDisplayMode(value);
|
||||
Q_EMIT DisplayModeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList DBusAdaptorDock::dockedApps() const
|
||||
{
|
||||
return parent()->getDockedApps();
|
||||
}
|
||||
|
||||
QList<QDBusObjectPath> DBusAdaptorDock::entries() const
|
||||
{
|
||||
QList<QDBusObjectPath> ret;
|
||||
for (auto path : parent()->getEntryPaths())
|
||||
ret.push_back(QDBusObjectPath(path));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DBusAdaptorDock::hideMode() const
|
||||
{
|
||||
return int(parent()->getHideMode());
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::setHideMode(int value)
|
||||
{
|
||||
if (hideMode() != value) {
|
||||
parent()->setHideMode(HideMode(value));
|
||||
Q_EMIT HideModeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int DBusAdaptorDock::hideState() const
|
||||
{
|
||||
return int(parent()->getHideState());
|
||||
}
|
||||
|
||||
uint DBusAdaptorDock::hideTimeout() const
|
||||
{
|
||||
return parent()->getHideTimeout();
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::setHideTimeout(uint value)
|
||||
{
|
||||
if (hideTimeout() != value) {
|
||||
parent()->setHideTimeout(value);
|
||||
Q_EMIT HideTimeoutChanged();
|
||||
}
|
||||
}
|
||||
|
||||
uint DBusAdaptorDock::windowSizeEfficient() const
|
||||
{
|
||||
return parent()->getWindowSizeEfficient();
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::setWindowSizeEfficient(uint value)
|
||||
{
|
||||
if (windowSizeEfficient() != value) {
|
||||
parent()->setWindowSizeEfficient(value);
|
||||
Q_EMIT WindowSizeEfficientChanged();
|
||||
}
|
||||
}
|
||||
|
||||
uint DBusAdaptorDock::windowSizeFashion() const
|
||||
{
|
||||
return parent()->getWindowSizeFashion();
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::setWindowSizeFashion(uint value)
|
||||
{
|
||||
if (windowSizeFashion() != value) {
|
||||
parent()->setWindowSizeFashion(value);
|
||||
Q_EMIT WindowSizeFashionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QRect DBusAdaptorDock::frontendWindowRect() const
|
||||
{
|
||||
return parent()->getFrontendWindowRect();
|
||||
}
|
||||
|
||||
double DBusAdaptorDock::opacity() const
|
||||
{
|
||||
return parent()->getOpacity();
|
||||
}
|
||||
|
||||
uint DBusAdaptorDock::iconSize() const
|
||||
{
|
||||
return parent()->getIconSize();
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::setIconSize(uint value)
|
||||
{
|
||||
if (iconSize() != value) {
|
||||
parent()->setIconSize(value);
|
||||
Q_EMIT IconSizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int DBusAdaptorDock::position() const
|
||||
{
|
||||
return parent()->getPosition();
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::setPosition(int value)
|
||||
{
|
||||
if (position() != value) {
|
||||
parent()->setPosition(value);
|
||||
Q_EMIT PositionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
uint DBusAdaptorDock::showTimeout() const
|
||||
{
|
||||
return parent()->getShowTimeout();
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::setShowTimeout(uint value)
|
||||
{
|
||||
if (showTimeout() != value) {
|
||||
parent()->setShowTimeout(value);
|
||||
Q_EMIT ShowTimeoutChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Dock *DBusAdaptorDock::parent() const
|
||||
{
|
||||
return static_cast<Dock *>(QObject::parent());
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::CloseWindow(uint win)
|
||||
{
|
||||
parent()->closeWindow(win);
|
||||
}
|
||||
|
||||
// for debug
|
||||
QStringList DBusAdaptorDock::GetEntryIDs()
|
||||
{
|
||||
return parent()->getEntryIDs();
|
||||
}
|
||||
|
||||
bool DBusAdaptorDock::IsDocked(const QString &desktopFile)
|
||||
{
|
||||
return parent()->isDocked(desktopFile);
|
||||
}
|
||||
|
||||
bool DBusAdaptorDock::IsOnDock(const QString &desktopFile)
|
||||
{
|
||||
return parent()->isOnDock(desktopFile);
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::MoveEntry(int index, int newIndex)
|
||||
{
|
||||
parent()->moveEntry(index, newIndex);
|
||||
}
|
||||
|
||||
QString DBusAdaptorDock::QueryWindowIdentifyMethod(uint win)
|
||||
{
|
||||
return parent()->queryWindowIdentifyMethod(win);
|
||||
}
|
||||
|
||||
bool DBusAdaptorDock::RequestDock(const QString &desktopFile, int index)
|
||||
{
|
||||
return parent()->requestDock(desktopFile, index);
|
||||
}
|
||||
|
||||
bool DBusAdaptorDock::RequestUndock(const QString &desktopFile)
|
||||
{
|
||||
return parent()->requestUndock(desktopFile);
|
||||
}
|
||||
|
||||
void DBusAdaptorDock::SetFrontendWindowRect(int x, int y, uint width, uint height)
|
||||
{
|
||||
parent()->setFrontendWindowRect(x, y, width, height);
|
||||
}
|
||||
|
193
src/modules/dock/dbusadaptordock.h
Normal file
193
src/modules/dock/dbusadaptordock.h
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DBUSADAPTORDOCK_H
|
||||
#define DBUSADAPTORDOCK_H
|
||||
|
||||
#include "dock.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QRect>
|
||||
|
||||
/*
|
||||
* Adaptor class for interface org.deepin.dde.daemon.Dock1
|
||||
*/
|
||||
class DBusAdaptorDock: public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.deepin.dde.daemon.Dock1")
|
||||
Q_CLASSINFO("D-Bus Introspection", ""
|
||||
" <interface name=\"org.deepin.dde.daemon.Dock1\">\n"
|
||||
" <method name=\"CloseWindow\">\n"
|
||||
" <arg direction=\"in\" type=\"u\" name=\"win\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"GetEntryIDs\">\n"
|
||||
" <arg direction=\"out\" type=\"as\" name=\"list\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"IsDocked\">\n"
|
||||
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
|
||||
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"IsOnDock\">\n"
|
||||
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
|
||||
" <arg direction=\"out\" type=\"b\" name=\"value\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"MoveEntry\">\n"
|
||||
" <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
|
||||
" <arg direction=\"in\" type=\"i\" name=\"newIndex\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"QueryWindowIdentifyMethod\">\n"
|
||||
" <arg direction=\"in\" type=\"u\" name=\"win\"/>\n"
|
||||
" <arg direction=\"out\" type=\"s\" name=\"identifyMethod\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"RequestDock\">\n"
|
||||
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
|
||||
" <arg direction=\"in\" type=\"i\" name=\"index\"/>\n"
|
||||
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"RequestUndock\">\n"
|
||||
" <arg direction=\"in\" type=\"s\" name=\"desktopFile\"/>\n"
|
||||
" <arg direction=\"out\" type=\"b\" name=\"ok\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"SetFrontendWindowRect\">\n"
|
||||
" <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
|
||||
" <arg direction=\"in\" type=\"i\" name=\"y\"/>\n"
|
||||
" <arg direction=\"in\" type=\"u\" name=\"width\"/>\n"
|
||||
" <arg direction=\"in\" type=\"u\" name=\"height\"/>\n"
|
||||
" </method>\n"
|
||||
" <signal name=\"ServiceRestarted\"/>\n"
|
||||
" <signal name=\"EntryAdded\">\n"
|
||||
" <arg type=\"o\" name=\"path\"/>\n"
|
||||
" <arg type=\"i\" name=\"index\"/>\n"
|
||||
" </signal>\n"
|
||||
" <signal name=\"EntryRemoved\">\n"
|
||||
" <arg type=\"s\" name=\"entryId\"/>\n"
|
||||
" </signal>\n"
|
||||
" <property access=\"readwrite\" type=\"u\" name=\"ShowTimeout\"/>\n"
|
||||
" <property access=\"readwrite\" type=\"u\" name=\"HideTimeout\"/>\n"
|
||||
" <property access=\"readwrite\" type=\"u\" name=\"WindowSizeEfficient\"/>\n"
|
||||
" <property access=\"readwrite\" type=\"u\" name=\"WindowSizeFashion\"/>\n"
|
||||
" <property access=\"read\" type=\"iiii\" name=\"FrontendWindowRect\"/>\n"
|
||||
" <property access=\"read\" type=\"d\" name=\"Opacity\"/>\n"
|
||||
" <property access=\"read\" type=\"ao\" name=\"Entries\"/>\n"
|
||||
" <property access=\"readwrite\" type=\"i\" name=\"HideMode\"/>\n"
|
||||
" <property access=\"readwrite\" type=\"i\" name=\"DisplayMode\"/>\n"
|
||||
" <property access=\"read\" type=\"i\" name=\"HideState\"/>\n"
|
||||
" <property access=\"readwrite\" type=\"i\" name=\"Position\"/>\n"
|
||||
" <property access=\"readwrite\" type=\"u\" name=\"IconSize\"/>\n"
|
||||
" <property access=\"read\" type=\"as\" name=\"DockedApps\"/>\n"
|
||||
" </interface>\n"
|
||||
"")
|
||||
public:
|
||||
DBusAdaptorDock(QObject *parent);
|
||||
virtual ~DBusAdaptorDock();
|
||||
|
||||
public: // PROPERTIES
|
||||
Q_PROPERTY(int DisplayMode READ displayMode WRITE setDisplayMode NOTIFY DisplayModeChanged)
|
||||
int displayMode() const;
|
||||
void setDisplayMode(int value);
|
||||
|
||||
Q_PROPERTY(QStringList DockedApps READ dockedApps NOTIFY DockedAppsChanged)
|
||||
QStringList dockedApps() const;
|
||||
|
||||
Q_PROPERTY(QList<QDBusObjectPath> Entries READ entries NOTIFY EntriesChanged)
|
||||
QList<QDBusObjectPath> entries() const;
|
||||
|
||||
Q_PROPERTY(int HideMode READ hideMode WRITE setHideMode NOTIFY HideModeChanged)
|
||||
int hideMode() const;
|
||||
void setHideMode(int value);
|
||||
|
||||
Q_PROPERTY(int HideState READ hideState NOTIFY HideStateChanged)
|
||||
int hideState() const;
|
||||
|
||||
Q_PROPERTY(uint HideTimeout READ hideTimeout WRITE setHideTimeout NOTIFY HideTimeoutChanged)
|
||||
uint hideTimeout() const;
|
||||
void setHideTimeout(uint value);
|
||||
|
||||
Q_PROPERTY(uint WindowSizeEfficient READ windowSizeEfficient WRITE setWindowSizeEfficient NOTIFY WindowSizeEfficientChanged)
|
||||
uint windowSizeEfficient() const;
|
||||
void setWindowSizeEfficient(uint value);
|
||||
|
||||
Q_PROPERTY(uint WindowSizeFashion READ windowSizeFashion WRITE setWindowSizeFashion NOTIFY WindowSizeFashionChanged)
|
||||
uint windowSizeFashion() const;
|
||||
void setWindowSizeFashion(uint value);
|
||||
|
||||
Q_PROPERTY(QRect FrontendWindowRect READ frontendWindowRect NOTIFY FrontendWindowRectChanged)
|
||||
QRect frontendWindowRect() const;
|
||||
|
||||
Q_PROPERTY(double Opacity READ opacity NOTIFY OpacityChanged)
|
||||
double opacity() const;
|
||||
|
||||
Q_PROPERTY(uint IconSize READ iconSize WRITE setIconSize NOTIFY IconSizeChanged)
|
||||
uint iconSize() const;
|
||||
void setIconSize(uint value);
|
||||
|
||||
Q_PROPERTY(int Position READ position WRITE setPosition NOTIFY PositionChanged)
|
||||
int position() const;
|
||||
void setPosition(int value);
|
||||
|
||||
Q_PROPERTY(uint ShowTimeout READ showTimeout WRITE setShowTimeout NOTIFY ShowTimeoutChanged)
|
||||
uint showTimeout() const;
|
||||
void setShowTimeout(uint value);
|
||||
|
||||
Dock *parent() const;
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
void CloseWindow(uint win);
|
||||
QStringList GetEntryIDs();
|
||||
bool IsDocked(const QString &desktopFile);
|
||||
bool IsOnDock(const QString &desktopFile);
|
||||
void MoveEntry(int index, int newIndex);
|
||||
QString QueryWindowIdentifyMethod(uint win);
|
||||
bool RequestDock(const QString &desktopFile, int index);
|
||||
bool RequestUndock(const QString &desktopFile);
|
||||
void SetFrontendWindowRect(int x, int y, uint width, uint height);
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void ServiceRestarted();
|
||||
void EntryAdded(const QDBusObjectPath &path, int index);
|
||||
void EntryRemoved(const QString &entryId);
|
||||
|
||||
void DisplayModeChanged();
|
||||
void DockedAppsChanged();
|
||||
void OpacityChanged();
|
||||
void EntriesChanged();
|
||||
void HideModeChanged();
|
||||
void WindowSizeEfficientChanged();
|
||||
void WindowSizeFashionChanged();
|
||||
void HideStateChanged();
|
||||
void FrontendWindowRectChanged();
|
||||
void HideTimeoutChanged();
|
||||
void IconSizeChanged();
|
||||
void PositionChanged();
|
||||
void ShowTimeoutChanged();
|
||||
};
|
||||
|
||||
#endif
|
177
src/modules/dock/dbusadaptorentry.cpp
Normal file
177
src/modules/dock/dbusadaptorentry.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dbusadaptorentry.h"
|
||||
|
||||
DBusAdaptorEntry::DBusAdaptorEntry(QObject *parent)
|
||||
: QDBusAbstractAdaptor(parent)
|
||||
{
|
||||
|
||||
// constructor
|
||||
setAutoRelaySignals(true);
|
||||
//qDBusRegisterMetaType<ExportWindowInfo>();
|
||||
|
||||
Entry *entry = static_cast<Entry *>(QObject::parent());
|
||||
if (entry) {
|
||||
connect(entry, &Entry::isActiveChanged, this, &DBusAdaptorEntry::IsActiveChanged);
|
||||
connect(entry, &Entry::isDockedChanged, this, &DBusAdaptorEntry::IsDockedChanged);
|
||||
connect(entry, &Entry::menuChanged, this, &DBusAdaptorEntry::MenuChanged);
|
||||
connect(entry, &Entry::iconChanged, this, &DBusAdaptorEntry::IconChanged);
|
||||
connect(entry, &Entry::nameChanged, this, &DBusAdaptorEntry::NameChanged);
|
||||
connect(entry, &Entry::desktopFileChanged, this, &DBusAdaptorEntry::DesktopFileChanged);
|
||||
connect(entry, &Entry::currentWindowChanged, this, &DBusAdaptorEntry::CurrentWindowChanged);
|
||||
}
|
||||
}
|
||||
|
||||
DBusAdaptorEntry::~DBusAdaptorEntry()
|
||||
{
|
||||
// destructor
|
||||
}
|
||||
|
||||
uint DBusAdaptorEntry::currentWindow() const
|
||||
{
|
||||
return parent()->getCurrentWindow();
|
||||
}
|
||||
|
||||
QString DBusAdaptorEntry::desktopFile() const
|
||||
{
|
||||
return parent()->getDesktopFile();
|
||||
}
|
||||
|
||||
QString DBusAdaptorEntry::icon() const
|
||||
{
|
||||
return parent()->getIcon();
|
||||
}
|
||||
|
||||
QString DBusAdaptorEntry::id() const
|
||||
{
|
||||
return parent()->getId();
|
||||
}
|
||||
|
||||
bool DBusAdaptorEntry::isActive() const
|
||||
{
|
||||
return parent()->getIsActive();
|
||||
}
|
||||
|
||||
bool DBusAdaptorEntry::isDocked() const
|
||||
{
|
||||
return parent()->getIsDocked();
|
||||
}
|
||||
|
||||
QString DBusAdaptorEntry::menu() const
|
||||
{
|
||||
return parent()->getMenu();
|
||||
}
|
||||
|
||||
QString DBusAdaptorEntry::name() const
|
||||
{
|
||||
return parent()->getName();
|
||||
}
|
||||
|
||||
/*
|
||||
QList<ExportWindowInfo> DBusAdaptorEntry::windowInfos()
|
||||
{
|
||||
return parent()->getExportWindowInfos();
|
||||
}
|
||||
*/
|
||||
Entry *DBusAdaptorEntry::parent() const
|
||||
{
|
||||
return static_cast<Entry *>(QObject::parent());
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::Activate(uint timestamp)
|
||||
{
|
||||
parent()->active(timestamp);
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::Check()
|
||||
{
|
||||
parent()->check();
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::ForceQuit()
|
||||
{
|
||||
parent()->forceQuit();
|
||||
}
|
||||
|
||||
QList<QVariant> DBusAdaptorEntry::GetAllowedCloseWindows()
|
||||
{
|
||||
auto ids = parent()->getAllowedClosedWindowIds();
|
||||
QList<QVariant> ret;
|
||||
for (auto id : ids)
|
||||
ret.push_back(id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::HandleDragDrop(uint timestamp, const QStringList &files)
|
||||
{
|
||||
parent()->handleDragDrop(timestamp, files);
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::HandleMenuItem(uint timestamp, const QString &id)
|
||||
{
|
||||
parent()->handleMenuItem(timestamp, id);
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::NewInstance(uint timestamp)
|
||||
{
|
||||
parent()->newInstance(timestamp);
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::PresentWindows()
|
||||
{
|
||||
parent()->presentWindows();
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::RequestDock()
|
||||
{
|
||||
parent()->requestDock();
|
||||
}
|
||||
|
||||
void DBusAdaptorEntry::RequestUndock()
|
||||
{
|
||||
parent()->requestUndock();
|
||||
}
|
||||
|
||||
|
||||
QDBusArgument &operator <<(QDBusArgument &argument, const ExportWindowInfo &info)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << info.xid << info.title << info.flash;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
const QDBusArgument &operator >>(const QDBusArgument &argument, ExportWindowInfo &info)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument >> info.xid >> info.title >> info.flash;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug deg, const ExportWindowInfo &info)
|
||||
{
|
||||
qDebug() << "xid: " << info.xid << " title:" << info.title << " flash:" << info.flash;
|
||||
|
||||
return deg;
|
||||
}
|
145
src/modules/dock/dbusadaptorentry.h
Normal file
145
src/modules/dock/dbusadaptorentry.h
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DBUSADAPTORENTRY_H
|
||||
#define DBUSADAPTORENTRY_H
|
||||
|
||||
#include "entry.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <DBusExtendedAbstractInterface>
|
||||
|
||||
Q_DECLARE_METATYPE(ExportWindowInfo)
|
||||
|
||||
QDBusArgument &operator <<(QDBusArgument &argument, const ExportWindowInfo &info);
|
||||
const QDBusArgument &operator >>(const QDBusArgument &argument, ExportWindowInfo &info);
|
||||
QDebug operator<<(QDebug deg, const ExportWindowInfo &info);
|
||||
|
||||
/*
|
||||
* Adaptor class for interface org.deepin.dde.daemon.Dock1.Entry
|
||||
*/
|
||||
class DBusAdaptorEntry: public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.deepin.dde.daemon.Dock1.Entry")
|
||||
Q_CLASSINFO("D-Bus Introspection", ""
|
||||
" <interface name=\"org.deepin.dde.daemon.Dock1.Entry\">\n"
|
||||
" <method name=\"Activate\">\n"
|
||||
" <arg direction=\"in\" type=\"u\" name=\"timestamp\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"Check\"/>\n"
|
||||
" <method name=\"ForceQuit\"/>\n"
|
||||
" <method name=\"GetAllowedCloseWindows\">\n"
|
||||
" <arg direction=\"out\" type=\"au\" name=\"windows\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"HandleDragDrop\">\n"
|
||||
" <arg direction=\"in\" type=\"u\" name=\"timestamp\"/>\n"
|
||||
" <arg direction=\"in\" type=\"as\" name=\"files\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"HandleMenuItem\">\n"
|
||||
" <arg direction=\"in\" type=\"u\" name=\"timestamp\"/>\n"
|
||||
" <arg direction=\"in\" type=\"s\" name=\"id\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"NewInstance\">\n"
|
||||
" <arg direction=\"in\" type=\"u\" name=\"timestamp\"/>\n"
|
||||
" </method>\n"
|
||||
" <method name=\"PresentWindows\"/>\n"
|
||||
" <method name=\"RequestDock\"/>\n"
|
||||
" <method name=\"RequestUndock\"/>\n"
|
||||
" <property access=\"read\" type=\"s\" name=\"Name\"/>\n"
|
||||
" <property access=\"read\" type=\"s\" name=\"Icon\"/>\n"
|
||||
" <property access=\"read\" type=\"s\" name=\"Id\"/>\n"
|
||||
" <property access=\"read\" type=\"b\" name=\"IsActive\"/>\n"
|
||||
" <property access=\"read\" type=\"u\" name=\"CurrentWindow\"/>\n"
|
||||
" <property access=\"read\" type=\"b\" name=\"IsDocked\"/>\n"
|
||||
" <property access=\"read\" type=\"s\" name=\"Menu\"/>\n"
|
||||
" <property access=\"read\" type=\"s\" name=\"DesktopFile\"/>\n"
|
||||
" <property access=\"read\" type=\"a(usb)\" name=\"WindowInfos\"/>\n"
|
||||
" </interface>\n"
|
||||
"")
|
||||
|
||||
public:
|
||||
DBusAdaptorEntry(QObject *parent);
|
||||
virtual ~DBusAdaptorEntry();
|
||||
|
||||
public: // PROPERTIES
|
||||
Q_PROPERTY(uint CurrentWindow READ currentWindow NOTIFY CurrentWindowChanged)
|
||||
uint currentWindow() const;
|
||||
|
||||
Q_PROPERTY(QString DesktopFile READ desktopFile NOTIFY DesktopFileChanged)
|
||||
QString desktopFile() const;
|
||||
|
||||
Q_PROPERTY(QString Icon READ icon NOTIFY IconChanged)
|
||||
QString icon() const;
|
||||
|
||||
Q_PROPERTY(QString Id READ id)
|
||||
QString id() const;
|
||||
|
||||
Q_PROPERTY(bool IsActive READ isActive NOTIFY IsActiveChanged)
|
||||
bool isActive() const;
|
||||
|
||||
Q_PROPERTY(bool IsDocked READ isDocked NOTIFY IsDockedChanged)
|
||||
bool isDocked() const;
|
||||
|
||||
Q_PROPERTY(QString Menu READ menu NOTIFY MenuChanged)
|
||||
QString menu() const;
|
||||
|
||||
Q_PROPERTY(QString Name READ name NOTIFY NameChanged)
|
||||
QString name() const;
|
||||
|
||||
//Q_PROPERTY(QString WindowInfos READ windowInfos)
|
||||
//QList<ExportWindowInfo> windowInfos();
|
||||
|
||||
Entry *parent() const;
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
void Activate(uint timestamp);
|
||||
void Check();
|
||||
void ForceQuit();
|
||||
QList<QVariant> GetAllowedCloseWindows();
|
||||
void HandleDragDrop(uint timestamp, const QStringList &files);
|
||||
void HandleMenuItem(uint timestamp, const QString &id);
|
||||
void NewInstance(uint timestamp);
|
||||
void PresentWindows();
|
||||
void RequestDock();
|
||||
void RequestUndock();
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void IsActiveChanged(bool value);
|
||||
void IsDockedChanged(bool value);
|
||||
void MenuChanged(QString value);
|
||||
void IconChanged(QString value);
|
||||
void NameChanged(QString value);
|
||||
void DesktopFileChanged(QString value);
|
||||
void CurrentWindowChanged(uint32_t value);
|
||||
};
|
||||
|
||||
#endif
|
214
src/modules/dock/dbushandler.cpp
Normal file
214
src/modules/dock/dbushandler.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dbushandler.h"
|
||||
#include "dock.h"
|
||||
#include "windowinfok.h"
|
||||
#include "dbusbamfapplication.h"
|
||||
|
||||
DBusHandler::DBusHandler(Dock *_dock, QObject *parent)
|
||||
: QObject(parent)
|
||||
, dock(_dock)
|
||||
, session(QDBusConnection::sessionBus())
|
||||
, launcherEnd(new LauncherBackEnd("org.deepin.dde.daemon.Launcher1", "/org/deepin/dde/daemon/Launcher1", session, this))
|
||||
, launcherFront(new LauncherFront("org.deepin.dde.Launcher1", "/org/deepin/dde/Launcher1", session, this))
|
||||
, wm(new com::deepin::WM("com.deepin.wm", "/com/deepin/wm", session, this))
|
||||
, wmSwitcher(new com::deepin::WMSwitcher("com.deepin.wmWMSwitcher", "/com/deepin/WMSwitcher", session, this))
|
||||
, kwaylandManager(nullptr)
|
||||
, bamfMatcher(new org::ayatana::bamf::BamfMatcher("org.ayatana.bamf.matcher", "/org/ayatana/bamf/matcher", session, this))
|
||||
{
|
||||
// 关联org.deepin.dde.daemon.Launcher1事件 ItemChanged
|
||||
connect(launcherEnd, &LauncherBackEnd::ItemChanged, this, &DBusHandler::handleLauncherItemChanged);
|
||||
|
||||
// 关联org.deepin.dde.Launcher1事件 VisibleChanged
|
||||
connect(launcherFront, &LauncherFront::VisibleChanged, this, [&](bool visible) {
|
||||
dock->setDdeLauncherVisible(visible);
|
||||
dock->updateHideState(false);
|
||||
});
|
||||
|
||||
// 关联com.deepin.WMSwitcher事件 WMChanged
|
||||
connect(wmSwitcher, &__WMSwitcher::WMChanged, this, [&](QString name) {dock->setWMName(name);});
|
||||
}
|
||||
|
||||
// 关联com.deepin.daemon.KWayland.WindowManager事件
|
||||
void DBusHandler::listenWaylandWMSignals()
|
||||
{
|
||||
kwaylandManager = new com::deepin::daemon::kwayland::WindowManager("com.deepin.daemon.KWayland", "/com/deepin/daemon/KWayland/WindowManager", session, this);
|
||||
|
||||
// ActiveWindowchanged
|
||||
connect(kwaylandManager, &__KwaylandManager::ActiveWindowChanged, this, &DBusHandler::handleWlActiveWindowchange);
|
||||
// WindowCreated
|
||||
connect(kwaylandManager, &__KwaylandManager::WindowCreated, this, [&] (const QString &ObjPath) {
|
||||
dock->registerWindowWayland(ObjPath);
|
||||
});
|
||||
// WindowRemove
|
||||
connect(kwaylandManager, &__KwaylandManager::WindowRemove, this, [&] (const QString &ObjPath) {
|
||||
dock->unRegisterWindowWayland(ObjPath);
|
||||
});
|
||||
}
|
||||
|
||||
void DBusHandler::handleLauncherItemChanged(const QString &status, LauncherItemInfo itemInfo, qlonglong categoryID)
|
||||
{
|
||||
qInfo() << "handleLauncherItemChanged status:" << status << " Name:" << itemInfo.Name << " ID:" << itemInfo.ID;
|
||||
if (status == "deleted") {
|
||||
dock->handleLauncherItemDeleted(itemInfo.Path);
|
||||
} else if (status == "created") {
|
||||
// don't need to download to dock when app reinstall
|
||||
} else if (status == "updated") {
|
||||
dock->handleLauncherItemUpdated(itemInfo.Path);
|
||||
}
|
||||
}
|
||||
|
||||
QString DBusHandler::getCurrentWM()
|
||||
{
|
||||
return wmSwitcher->CurrentWM().value();
|
||||
}
|
||||
|
||||
// TODO 扩展ApplicationManager Run接口,允许带参数启动应用,暂时调用StartManager接口
|
||||
void DBusHandler::launchApp(uint32_t timestamp, QStringList files)
|
||||
{
|
||||
QDBusInterface interface = QDBusInterface("com.deepin.StartManager", "/com/deepin/StartManager", "com.deepin.StartManager");
|
||||
interface.call("LaunchApp", files, timestamp);
|
||||
}
|
||||
|
||||
void DBusHandler::launchAppAction(uint32_t timestamp, QString file, QString section)
|
||||
{
|
||||
QDBusInterface interface = QDBusInterface("com.deepin.StartManager", "/com/deepin/StartManager", "com.deepin.StartManager");
|
||||
interface.call("LaunchAppAction", file, section, timestamp);
|
||||
}
|
||||
|
||||
void DBusHandler::markAppLaunched(const QString &filePath)
|
||||
{
|
||||
QDBusInterface interface = QDBusInterface("org.deepin.daemon.AlRecorder1", "/org/deepin/daemon/AlRecorder1", "org.deepin.daemon.AlRecorder1");
|
||||
interface.call("MarkLaunched", filePath);
|
||||
}
|
||||
|
||||
bool DBusHandler::wlShowingDesktop()
|
||||
{
|
||||
bool ret = false;
|
||||
if (kwaylandManager)
|
||||
ret = kwaylandManager->IsShowingDesktop().value();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint DBusHandler::wlActiveWindow()
|
||||
{
|
||||
uint ret = 0;
|
||||
if (kwaylandManager)
|
||||
ret = kwaylandManager->ActiveWindow().value();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DBusHandler::handleWlActiveWindowchange()
|
||||
{
|
||||
uint activeWinInternalId = wlActiveWindow();
|
||||
if (activeWinInternalId == 0)
|
||||
return;
|
||||
|
||||
WindowInfoK *info = dock->handleActiveWindowChangedK(activeWinInternalId);
|
||||
if (info->getXid() != 0) {
|
||||
dock->handleActiveWindowChanged(info);
|
||||
} else {
|
||||
dock->updateHideState(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DBusHandler::listenKWindowSignals(WindowInfoK *windowInfo)
|
||||
{
|
||||
PlasmaWindow *window = windowInfo->getPlasmaWindow();
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
// Title changed
|
||||
connect(window, &PlasmaWindow::TitleChanged, this, [&] {
|
||||
windowInfo->updateTitle();
|
||||
auto entry = dock->getEntryByWindowId(windowInfo->getXid());
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
if (entry->getCurrentWindowInfo() == windowInfo)
|
||||
entry->updateName();
|
||||
|
||||
entry->updateWindowInfos();
|
||||
});
|
||||
|
||||
// Icon changed
|
||||
connect(window, &PlasmaWindow::IconChanged, this, [&] {
|
||||
windowInfo->updateIcon();
|
||||
auto entry = dock->getEntryByWindowId(windowInfo->getXid());
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
entry->updateIcon();
|
||||
});
|
||||
|
||||
// DemandingAttention changed
|
||||
connect(window, &PlasmaWindow::DemandsAttentionChanged, this, [&] {
|
||||
windowInfo->updateDemandingAttention();
|
||||
auto entry = dock->getEntryByWindowId(windowInfo->getXid());
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
entry->updateWindowInfos();
|
||||
});
|
||||
|
||||
// Geometry changed
|
||||
connect(window, &PlasmaWindow::GeometryChanged, this, [&] {
|
||||
if (!windowInfo->updateGeometry())
|
||||
return;
|
||||
|
||||
dock->handleWindowGeometryChanged();
|
||||
});
|
||||
}
|
||||
|
||||
PlasmaWindow *DBusHandler::createPlasmaWindow(QString objPath)
|
||||
{
|
||||
return new PlasmaWindow("com.deepin.daemon.KWayland.PlasmaWindow", objPath, session, this);
|
||||
}
|
||||
|
||||
// 取消关联信号
|
||||
void DBusHandler::removePlasmaWindowHandler(PlasmaWindow *window)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DBusHandler::presentWindows(QList<uint> windows)
|
||||
{
|
||||
wm->PresentWindows(windows);
|
||||
}
|
||||
|
||||
QString DBusHandler::getDesktopFromWindowByBamf(XWindow windowId)
|
||||
{
|
||||
QDBusPendingReply<QString> reply = bamfMatcher->ApplicationForXid(windowId);
|
||||
if (!reply.isValid())
|
||||
return "";
|
||||
|
||||
QString appObjPath = reply.value();
|
||||
|
||||
org::ayatana::bamf::BamfApplication bamfApp("org.ayatana.bamf.application", appObjPath, session, this);
|
||||
if (bamfApp.isValid())
|
||||
return bamfApp.DesktopFile();
|
||||
|
||||
return "";
|
||||
}
|
||||
|
92
src/modules/dock/dbushandler.h
Normal file
92
src/modules/dock/dbushandler.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DBUSHANDLER_H
|
||||
#define DBUSHANDLER_H
|
||||
|
||||
#include "dbuslauncher.h"
|
||||
#include "dbuslauncherfront.h"
|
||||
#include "dbuswm.h"
|
||||
#include "dbuswmswitcher.h"
|
||||
#include "dbuskwaylandwindowmanager.h"
|
||||
#include "windowinfok.h"
|
||||
#include "dbusplasmawindow.h"
|
||||
#include "dbusbamfmatcher.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
|
||||
class Dock;
|
||||
|
||||
// 处理DBus交互
|
||||
class DBusHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DBusHandler(Dock *_dock, QObject *parent = nullptr);
|
||||
|
||||
/************************* KWayland/WindowManager ***************************/
|
||||
void listenWaylandWMSignals();
|
||||
bool wlShowingDesktop();
|
||||
uint wlActiveWindow();
|
||||
|
||||
/************************* daemon.Launcher1 ***************************/
|
||||
void handleLauncherItemChanged(const QString &status, LauncherItemInfo itemInfo, qlonglong categoryID);
|
||||
|
||||
/************************* WMSwitcher ***************************/
|
||||
QString getCurrentWM();
|
||||
|
||||
/************************* StartManager ***************************/
|
||||
void launchApp(uint32_t timestamp, QStringList files);
|
||||
void launchAppAction(uint32_t timestamp, QString file, QString section);
|
||||
|
||||
/************************* AlRecorder1 ***************************/
|
||||
void markAppLaunched(const QString &filePath);
|
||||
|
||||
/************************* KWayland.PlasmaWindow ***************************/
|
||||
void listenKWindowSignals(WindowInfoK *windowInfo);
|
||||
PlasmaWindow *createPlasmaWindow(QString objPath);
|
||||
void removePlasmaWindowHandler(PlasmaWindow *window);
|
||||
|
||||
/************************* WM ***************************/
|
||||
void presentWindows(QList<uint> windows);
|
||||
|
||||
/************************* bamf ***************************/
|
||||
// XWindow -> desktopFile
|
||||
QString getDesktopFromWindowByBamf(XWindow windowId);
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleWlActiveWindowchange();
|
||||
|
||||
private:
|
||||
Dock *dock;
|
||||
QDBusConnection session;
|
||||
|
||||
LauncherBackEnd *launcherEnd;
|
||||
LauncherFront *launcherFront;
|
||||
com::deepin::WM *wm;
|
||||
com::deepin::WMSwitcher *wmSwitcher;
|
||||
com::deepin::daemon::kwayland::WindowManager *kwaylandManager;
|
||||
org::ayatana::bamf::BamfMatcher *bamfMatcher;
|
||||
};
|
||||
|
||||
#endif // DBUSHANDLER_H
|
1045
src/modules/dock/dock.cpp
Normal file
1045
src/modules/dock/dock.cpp
Normal file
File diff suppressed because it is too large
Load Diff
191
src/modules/dock/dock.h
Normal file
191
src/modules/dock/dock.h
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DOCK_H
|
||||
#define DOCK_H
|
||||
|
||||
#include "synmodule.h"
|
||||
#include "docksettings.h"
|
||||
#include "entries.h"
|
||||
#include "dbusplasmawindow.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
#include <QMutex>
|
||||
|
||||
class WindowIdentify;
|
||||
class DBusHandler;
|
||||
class WaylandManager;
|
||||
class X11Manager;
|
||||
class WindowInfoK;
|
||||
class WindowInfoX;
|
||||
|
||||
// 任务栏
|
||||
class Dock : public SynModule
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum class HideState
|
||||
{
|
||||
Unknown,
|
||||
Show,
|
||||
Hide,
|
||||
};
|
||||
|
||||
public:
|
||||
explicit Dock(QObject *parent = nullptr);
|
||||
~Dock();
|
||||
|
||||
bool dockEntry(Entry *entry);
|
||||
void undockEntry(Entry *entry);
|
||||
QString allocEntryId();
|
||||
bool shouldShowOnDock(WindowInfoBase *info);
|
||||
void setDdeLauncherVisible(bool visible);
|
||||
QString getWMName();
|
||||
void setWMName(QString name);
|
||||
void setPropHideMode(HideState state);
|
||||
void attachOrDetachWindow(WindowInfoBase *info);
|
||||
void attachWindow(WindowInfoBase *info);
|
||||
void detachWindow(WindowInfoBase *info);
|
||||
void markAppLaunched(const QString &filePath);
|
||||
void launchApp(uint32_t timestamp, QStringList files);
|
||||
void launchAppAction(uint32_t timestamp, QString file, QString section);
|
||||
bool is3DWM();
|
||||
bool isWaylandEnv();
|
||||
WindowInfoK *handleActiveWindowChangedK(uint activeWin);
|
||||
void handleActiveWindowChanged(WindowInfoBase *info);
|
||||
void saveDockedApps();
|
||||
void removeAppEntry(Entry *entry);
|
||||
void handleWindowGeometryChanged();
|
||||
Entry *getEntryByWindowId(XWindow windowId);
|
||||
QString getDesktopFromWindowByBamf(XWindow windowId);
|
||||
|
||||
void registerWindowWayland(const QString &objPath);
|
||||
void unRegisterWindowWayland(const QString &objPath);
|
||||
|
||||
AppInfo *identifyWindow(WindowInfoBase *winInfo, QString &innerId);
|
||||
void markAppLaunched(AppInfo *appInfo);
|
||||
void deleteWindow(XWindow xid);
|
||||
|
||||
ForceQuitAppMode getForceQuitAppStatus();
|
||||
QVector<QString> getWinIconPreferredApps();
|
||||
void handleLauncherItemDeleted(QString itemPath);
|
||||
void handleLauncherItemUpdated(QString itemPath);
|
||||
|
||||
double getOpacity();
|
||||
QRect getFrontendWindowRect();
|
||||
int getDisplayMode();
|
||||
void setDisplayMode(int mode);
|
||||
QStringList getDockedApps();
|
||||
QStringList getEntryPaths();
|
||||
HideMode getHideMode();
|
||||
void setHideMode(HideMode mode);
|
||||
HideState getHideState();
|
||||
void setHideState(HideState state);
|
||||
uint getHideTimeout();
|
||||
void setHideTimeout(uint timeout);
|
||||
uint getIconSize();
|
||||
void setIconSize(uint size);
|
||||
int getPosition();
|
||||
void setPosition(int position);
|
||||
uint getShowTimeout();
|
||||
void setShowTimeout(uint timeout);
|
||||
uint getWindowSizeEfficient();
|
||||
void setWindowSizeEfficient(uint size);
|
||||
uint getWindowSizeFashion();
|
||||
void setWindowSizeFashion(uint size);
|
||||
|
||||
// 设置配置
|
||||
void setSynConfig(QByteArray ba);
|
||||
QByteArray getSyncConfig();
|
||||
|
||||
/******************************** dbus handler ****************************/
|
||||
PlasmaWindow *createPlasmaWindow(QString objPath);
|
||||
void listenKWindowSignals(WindowInfoK *windowInfo);
|
||||
void removePlasmaWindowHandler(PlasmaWindow *window);
|
||||
void presentWindows(QList<uint> windows);
|
||||
|
||||
HideMode getDockHideMode();
|
||||
WindowInfoBase *getActiveWindow();
|
||||
QList<XWindow> getClientList();
|
||||
|
||||
void closeWindow(XWindow windowId);
|
||||
QStringList getEntryIDs();
|
||||
void setFrontendWindowRect(int32_t x, int32_t y, uint width, uint height);
|
||||
bool isDocked(const QString desktopFile);
|
||||
bool requestDock(QString desktopFile, int index);
|
||||
bool requestUndock(QString desktopFile);
|
||||
void moveEntry(int oldIndex, int newIndex);
|
||||
bool isOnDock(QString desktopFile);
|
||||
QString queryWindowIdentifyMethod(XWindow windowId);
|
||||
QStringList getDockedAppsDesktopFiles();
|
||||
QString getPluginSettings();
|
||||
void setPluginSettings(QString jsonStr);
|
||||
void mergePluginSettings(QString jsonStr);
|
||||
void removePluginSettings(QString pluginName, QStringList settingkeys);
|
||||
|
||||
void updateHideState(bool delay);
|
||||
|
||||
Q_SIGNALS:
|
||||
void serviceRestarted();
|
||||
void entryAdded(QString entryObjPath, int32_t index);
|
||||
void entryRemoved(QString id);
|
||||
void hideStateChanged();
|
||||
void frontendWindowRectChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void smartHideModeTimerExpired();
|
||||
|
||||
private:
|
||||
void initSettings();
|
||||
void updateMenu();
|
||||
void initEntries();
|
||||
void initDockedApps();
|
||||
void initClientList();
|
||||
WindowInfoX *findWindowByXidX(XWindow xid);
|
||||
WindowInfoK *findWindowByXidK(XWindow xid);
|
||||
bool isWindowDockOverlapX(XWindow xid);
|
||||
bool isWindowDockOverlapK(WindowInfoBase *info);
|
||||
Entry *getDockedEntryByDesktopFile(const QString &desktopFile);
|
||||
bool shouldHideOnSmartHideMode();
|
||||
QVector<XWindow> getActiveWinGroup(XWindow xid);
|
||||
|
||||
WindowIdentify *windowIdentify; // 窗口识别
|
||||
Entries *entries; // 所有应用实例
|
||||
int entriesSum; // 累计打开的应用数量
|
||||
bool ddeLauncherVisible; // 前端启动器是否可见
|
||||
QString wmName; // 窗管名称
|
||||
WaylandManager *waylandManager; // wayland窗口管理
|
||||
X11Manager *x11Manager; // X11窗口管理
|
||||
QList<XWindow> clientList; // 所有窗口
|
||||
QRect frontendWindowRect; // 前端任务栏大小, 用于智能隐藏时判断窗口是否重合
|
||||
HideState hideState; // 记录任务栏隐藏状态
|
||||
QTimer *smartHideTimer; // 任务栏智能隐藏定时器
|
||||
WindowInfoBase *activeWindow;// 记录当前活跃窗口信息
|
||||
WindowInfoBase *activeWindowOld;// 记录前一个活跃窗口信息
|
||||
bool isWayland; // 判断是否为wayland环境
|
||||
ForceQuitAppMode forceQuitAppStatus; // 强制退出应用状态
|
||||
DBusHandler *dbusHandler; // 处理dbus交互
|
||||
QMutex windowOperateMutex; // 窗口合并或拆分锁
|
||||
};
|
||||
|
||||
|
||||
#endif // DOCK_H
|
52
src/modules/dock/dockmanager.cpp
Normal file
52
src/modules/dock/dockmanager.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dockmanager.h"
|
||||
#include "dock.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDebug>
|
||||
#include <QDBusError>
|
||||
|
||||
DockManager::DockManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, dock(new Dock(this))
|
||||
{
|
||||
adaptor = new DBusAdaptorDock(dock);
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
if (!con.registerService(dbusService)) {
|
||||
qWarning() << "register service Dock1 error:" << con.lastError().message();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!con.registerObject(dbusPath, dock, QDBusConnection::ExportAdaptors))
|
||||
{
|
||||
qWarning() << "register object Dock1 error:" << con.lastError().message();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
DockManager::~DockManager()
|
||||
{
|
||||
|
||||
}
|
48
src/modules/dock/dockmanager.h
Normal file
48
src/modules/dock/dockmanager.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DOCKMANAGER_H
|
||||
#define DOCKMANAGER_H
|
||||
|
||||
#include "dbusadaptordock.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class Dock;
|
||||
|
||||
// 任务栏管理类
|
||||
class DockManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DockManager(QObject *parent = nullptr);
|
||||
~DockManager();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
private:
|
||||
Dock *dock;
|
||||
DBusAdaptorDock *adaptor;
|
||||
};
|
||||
|
||||
#endif // DOCKMANAGER_H
|
354
src/modules/dock/docksettings.cpp
Normal file
354
src/modules/dock/docksettings.cpp
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "docksettings.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <DConfig>
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
DCORE_USE_NAMESPACE
|
||||
|
||||
static DConfig *dockSettings = Settings::ConfigPtr(configDock);
|
||||
static DConfig *appearanceSettings = Settings::ConfigPtr(configAppearance);
|
||||
|
||||
DockSettings::DockSettings(QObject *parent)
|
||||
: QObject (parent)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void DockSettings::init()
|
||||
{
|
||||
// 绑定属性
|
||||
if (dockSettings) {
|
||||
connect(dockSettings, &DConfig::valueChanged, this, [&] (const QString &key) {
|
||||
if (key == keyHideMode) {
|
||||
Q_EMIT hideModeChanged(HideMode(dockSettings->value(key).toInt()));
|
||||
} else if(key == keyDisplayMode) {
|
||||
Q_EMIT displayModeChanged(DisplayMode(dockSettings->value(key).toInt()));
|
||||
} else if (key == keyPosition) {
|
||||
Q_EMIT positionModeChanged(PositonMode(dockSettings->value(key).toInt()));
|
||||
} else if (key == keyForceQuitApp){
|
||||
Q_EMIT forceQuitAppChanged(dockSettings->value(key).toBool());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
HideMode DockSettings::getHideMode()
|
||||
{
|
||||
HideMode ret = HideMode::Unknown;
|
||||
if (dockSettings) {
|
||||
QString mode = dockSettings->value(keyHideMode).toString();
|
||||
HideModeHandler handler(mode);
|
||||
ret = handler.toEnum();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DockSettings::setHideMode(HideMode mode)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyHideMode, HideModeHandler(mode).toString());
|
||||
}
|
||||
}
|
||||
|
||||
DisplayMode DockSettings::getDisplayMode()
|
||||
{
|
||||
DisplayMode ret = DisplayMode::Unknown;
|
||||
if (dockSettings) {
|
||||
QString mode = dockSettings->value(keyDisplayMode).toString();
|
||||
DisplayModeHandler handler(mode);
|
||||
ret = handler.toEnum();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DockSettings::setDisplayMode(DisplayMode mode)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyHideMode, DisplayModeHandler(mode).toString());
|
||||
}
|
||||
}
|
||||
|
||||
PositonMode DockSettings::getPositionMode()
|
||||
{
|
||||
PositonMode ret = PositonMode::Unknown;
|
||||
if (dockSettings) {
|
||||
QString mode = dockSettings->value(keyPosition).toString();
|
||||
PositonModeHandler handler(mode);
|
||||
ret = handler.toEnum();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DockSettings::setPositionMode(PositonMode mode)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyPosition, PositonModeHandler(mode).toString());
|
||||
}
|
||||
}
|
||||
|
||||
ForceQuitAppMode DockSettings::getForceQuitAppMode()
|
||||
{
|
||||
ForceQuitAppMode ret = ForceQuitAppMode::Unknown;
|
||||
if (dockSettings) {
|
||||
QString mode = dockSettings->value(keyForceQuitApp).toString();
|
||||
ForceQuitAppModeHandler handler(mode);
|
||||
ret = handler.toEnum();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DockSettings::setForceQuitAppMode(ForceQuitAppMode mode)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyForceQuitApp, ForceQuitAppModeHandler(mode).toString());
|
||||
}
|
||||
}
|
||||
|
||||
uint DockSettings::getIconSize()
|
||||
{
|
||||
uint size = 36;
|
||||
if (dockSettings) {
|
||||
size = dockSettings->value(keyIconSize).toUInt();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void DockSettings::setIconSize(uint size)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyIconSize, size);
|
||||
}
|
||||
}
|
||||
|
||||
uint DockSettings::getShowTimeout()
|
||||
{
|
||||
uint time = 100;
|
||||
if (dockSettings) {
|
||||
time = dockSettings->value(keyShowTimeout).toUInt();
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
void DockSettings::setShowTimeout(uint time)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyShowTimeout, time);
|
||||
}
|
||||
}
|
||||
|
||||
uint DockSettings::getHideTimeout()
|
||||
{
|
||||
uint time = 0;
|
||||
if (dockSettings) {
|
||||
time = dockSettings->value(keyHideTimeout).toUInt();
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
void DockSettings::setHideTimeout(uint time)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyHideTimeout, time);
|
||||
}
|
||||
}
|
||||
|
||||
uint DockSettings::getWindowSizeEfficient()
|
||||
{
|
||||
uint size = 40;
|
||||
if (dockSettings) {
|
||||
size = dockSettings->value(keyWindowSizeEfficient).toUInt();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void DockSettings::setWindowSizeEfficient(uint size)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyWindowSizeEfficient, size);
|
||||
}
|
||||
}
|
||||
|
||||
uint DockSettings::getWindowSizeFashion()
|
||||
{
|
||||
uint size = 48;
|
||||
if (dockSettings) {
|
||||
size = dockSettings->value(keyWindowSizeFashion).toUInt();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void DockSettings::setWindowSizeFashion(uint size)
|
||||
{
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyWindowSizeFashion, size);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList DockSettings::getDockedApps()
|
||||
{
|
||||
QStringList ret;
|
||||
if (!dockSettings)
|
||||
return ret;
|
||||
|
||||
for(const auto &var : dockSettings->value(keyDockedApps).toList()) {
|
||||
if (var.isValid())
|
||||
ret.push_back(var.toString());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DockSettings::setDockedApps(QList<QString> &apps)
|
||||
{
|
||||
if (!dockSettings)
|
||||
return;
|
||||
|
||||
qDebug() << "docked apps:" << apps;
|
||||
QVariantList list;
|
||||
for (auto app : apps) {
|
||||
list << QVariant(app);
|
||||
}
|
||||
|
||||
dockSettings->setValue(keyDockedApps, list);
|
||||
}
|
||||
|
||||
double DockSettings::getOpacity()
|
||||
{
|
||||
double opacity = 0.4;
|
||||
if (appearanceSettings) {
|
||||
opacity = appearanceSettings->value(keyOpacity).toDouble();
|
||||
}
|
||||
return opacity;
|
||||
}
|
||||
|
||||
QVector<QString> DockSettings::getWinIconPreferredApps()
|
||||
{
|
||||
QVector<QString> ret;
|
||||
if (dockSettings) {
|
||||
for(const auto &var : dockSettings->value(keyWinIconPreferredApps).toList()) {
|
||||
if (var.isValid())
|
||||
ret.push_back(var.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString DockSettings::getPluginSettings()
|
||||
{
|
||||
QString ret;
|
||||
if (dockSettings) {
|
||||
ret = dockSettings->value(keyPluginSettings).toString();
|
||||
}
|
||||
|
||||
qInfo() << "getpluginsettings:" << ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DockSettings::setPluginSettings(QString jsonStr)
|
||||
{
|
||||
if (jsonStr.isEmpty())
|
||||
return;
|
||||
|
||||
if (dockSettings) {
|
||||
dockSettings->setValue(keyPluginSettings, jsonStr);
|
||||
}
|
||||
}
|
||||
|
||||
void DockSettings::mergePluginSettings(QString jsonStr)
|
||||
{
|
||||
QString origin = getPluginSettings();
|
||||
QJsonObject originSettings = plguinSettingsStrToObj(origin);
|
||||
QJsonObject needMergeSettings = plguinSettingsStrToObj(jsonStr);
|
||||
for (auto pluginsIt = needMergeSettings.begin(); pluginsIt != needMergeSettings.end(); pluginsIt++) {
|
||||
const QString &pluginName = pluginsIt.key();
|
||||
const QJsonObject &needMergeSettingsObj = pluginsIt.value().toObject();
|
||||
QJsonObject originSettingsObj = originSettings.value(pluginName).toObject();
|
||||
for (auto settingsIt = needMergeSettingsObj.begin(); settingsIt != needMergeSettingsObj.end(); settingsIt++) {
|
||||
originSettingsObj.insert(settingsIt.key(), settingsIt.value());
|
||||
}
|
||||
|
||||
// 重写plugin对应的设置
|
||||
originSettings.remove(pluginName);
|
||||
originSettings.insert(pluginName, originSettingsObj);
|
||||
}
|
||||
|
||||
setPluginSettings(QJsonDocument(originSettings).toJson(QJsonDocument::JsonFormat::Compact));
|
||||
}
|
||||
|
||||
void DockSettings::removePluginSettings(QString pluginName, QStringList settingkeys)
|
||||
{
|
||||
if (pluginName.isEmpty())
|
||||
return;
|
||||
|
||||
QString origin = getPluginSettings();
|
||||
QJsonObject originSettings = plguinSettingsStrToObj(origin);
|
||||
if (settingkeys.size() == 0) {
|
||||
originSettings.remove(pluginName);
|
||||
} else {
|
||||
for (auto pluginsIt = originSettings.begin(); pluginsIt != originSettings.end(); pluginsIt++) {
|
||||
const QString &pluginName = pluginsIt.key();
|
||||
if (pluginName != pluginName)
|
||||
continue;
|
||||
|
||||
QJsonObject originSettingsObj = originSettings.value(pluginName).toObject();
|
||||
for (const auto &key : settingkeys) {
|
||||
originSettingsObj.remove(key);
|
||||
}
|
||||
|
||||
// 重写plugin对应的设置
|
||||
originSettings.remove(pluginName);
|
||||
originSettings.insert(pluginName, originSettingsObj);
|
||||
}
|
||||
}
|
||||
|
||||
setPluginSettings(QJsonDocument(originSettings).toJson(QJsonDocument::JsonFormat::Compact));
|
||||
}
|
||||
|
||||
// 借鉴自dde-dock
|
||||
QJsonObject DockSettings::plguinSettingsStrToObj(QString jsonStr)
|
||||
{
|
||||
QJsonObject ret;
|
||||
const QJsonObject &pluginSettingsObject = QJsonDocument::fromJson(jsonStr.toLocal8Bit()).object();
|
||||
if (pluginSettingsObject.isEmpty()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (auto pluginsIt = pluginSettingsObject.constBegin(); pluginsIt != pluginSettingsObject.constEnd(); ++pluginsIt) {
|
||||
const QString &pluginName = pluginsIt.key();
|
||||
const QJsonObject &settingsObject = pluginsIt.value().toObject();
|
||||
QJsonObject newSettingsObject = ret.value(pluginName).toObject();
|
||||
for (auto settingsIt = settingsObject.constBegin(); settingsIt != settingsObject.constEnd(); ++settingsIt) {
|
||||
newSettingsObject.insert(settingsIt.key(), settingsIt.value());
|
||||
}
|
||||
// TODO: remove not exists key-values
|
||||
ret.insert(pluginName, newSettingsObject);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
275
src/modules/dock/docksettings.h
Normal file
275
src/modules/dock/docksettings.h
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DOCKSETTINGS_H
|
||||
#define DOCKSETTINGS_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
// 隐藏模式
|
||||
enum class HideMode {
|
||||
KeepShowing,
|
||||
KeepHidden,
|
||||
SmartHide,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
class HideModeHandler {
|
||||
HideMode modeEnum;
|
||||
QString modeStr;
|
||||
|
||||
public:
|
||||
HideModeHandler(HideMode mode) : modeEnum(mode), modeStr("") {}
|
||||
HideModeHandler(QString mode) : modeEnum(HideMode::Unknown), modeStr(mode) {}
|
||||
|
||||
bool equal(HideModeHandler hideMode) {
|
||||
return toString() == hideMode.toString() || toEnum() == hideMode.toEnum();
|
||||
}
|
||||
|
||||
QString toString() {
|
||||
switch (modeEnum) {
|
||||
case HideMode::KeepShowing:
|
||||
return "keep-showing";
|
||||
case HideMode::KeepHidden:
|
||||
return "keep-hidden";
|
||||
case HideMode::SmartHide:
|
||||
return "smart-hide";
|
||||
case HideMode::Unknown:
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
HideMode toEnum() {
|
||||
if (modeStr == "keep-showing")
|
||||
return HideMode::KeepHidden;
|
||||
else if (modeStr == "keep-hidden")
|
||||
return HideMode::KeepHidden;
|
||||
else if (modeStr == "smart-hide")
|
||||
return HideMode::SmartHide;
|
||||
else
|
||||
return HideMode::Unknown;
|
||||
}
|
||||
};
|
||||
|
||||
// 显示样式
|
||||
enum class DisplayMode {
|
||||
Fashion,
|
||||
Efficient,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
class DisplayModeHandler {
|
||||
DisplayMode modeEnum;
|
||||
QString modeStr;
|
||||
|
||||
public:
|
||||
DisplayModeHandler(DisplayMode mode) : modeEnum(mode), modeStr("") {}
|
||||
DisplayModeHandler(QString mode) : modeEnum(DisplayMode::Unknown), modeStr(mode) {}
|
||||
|
||||
bool equal(DisplayModeHandler displayMode) {
|
||||
return toString() == displayMode.toString() || toEnum() == displayMode.toEnum();
|
||||
}
|
||||
|
||||
QString toString() {
|
||||
switch (modeEnum) {
|
||||
case DisplayMode::Fashion:
|
||||
return "fashion";
|
||||
case DisplayMode::Efficient:
|
||||
return "efficient";
|
||||
case DisplayMode::Unknown:
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
DisplayMode toEnum() {
|
||||
if (modeStr == "fashion")
|
||||
return DisplayMode::Fashion;
|
||||
else if (modeStr == "efficient")
|
||||
return DisplayMode::Efficient;
|
||||
else
|
||||
return DisplayMode::Unknown;
|
||||
}
|
||||
};
|
||||
|
||||
// 显示位置
|
||||
enum class PositonMode {
|
||||
TOP,
|
||||
Right,
|
||||
Bottom,
|
||||
Left,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
class PositonModeHandler {
|
||||
PositonMode modeEnum;
|
||||
QString modeStr;
|
||||
|
||||
public:
|
||||
PositonModeHandler(PositonMode mode) : modeEnum(mode), modeStr("") {}
|
||||
PositonModeHandler(QString mode) : modeEnum(PositonMode::Unknown), modeStr(mode) {}
|
||||
|
||||
bool equal(PositonModeHandler displayMode) {
|
||||
return toString() == displayMode.toString() || toEnum() == displayMode.toEnum();
|
||||
}
|
||||
|
||||
QString toString() {
|
||||
switch (modeEnum) {
|
||||
case PositonMode::TOP:
|
||||
return "top";
|
||||
case PositonMode::Right:
|
||||
return "right";
|
||||
case PositonMode::Bottom:
|
||||
return "bottom";
|
||||
case PositonMode::Left:
|
||||
return "left";
|
||||
case PositonMode::Unknown:
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
PositonMode toEnum() {
|
||||
if (modeStr == "top")
|
||||
return PositonMode::TOP;
|
||||
else if (modeStr == "right")
|
||||
return PositonMode::Right;
|
||||
else if (modeStr == "bottom")
|
||||
return PositonMode::Bottom;
|
||||
else if (modeStr == "left")
|
||||
return PositonMode::Left;
|
||||
else
|
||||
return PositonMode::Unknown;
|
||||
}
|
||||
};
|
||||
|
||||
// 强制退出应用菜单状态
|
||||
enum class ForceQuitAppMode {
|
||||
Enabled, // 开启
|
||||
Disabled, // 关闭
|
||||
Deactivated, // 置灰
|
||||
Unknown
|
||||
};
|
||||
|
||||
class ForceQuitAppModeHandler {
|
||||
ForceQuitAppMode modeEnum;
|
||||
QString modeStr;
|
||||
|
||||
public:
|
||||
ForceQuitAppModeHandler(ForceQuitAppMode mode) : modeEnum(mode), modeStr("") {}
|
||||
ForceQuitAppModeHandler(QString mode) : modeEnum(ForceQuitAppMode::Unknown), modeStr(mode) {}
|
||||
|
||||
bool equal(ForceQuitAppModeHandler displayMode) {
|
||||
return toString() == displayMode.toString() || toEnum() == displayMode.toEnum();
|
||||
}
|
||||
|
||||
QString toString() {
|
||||
switch (modeEnum) {
|
||||
case ForceQuitAppMode::Enabled:
|
||||
return "enabled";
|
||||
case ForceQuitAppMode::Disabled:
|
||||
return "disabled";
|
||||
case ForceQuitAppMode::Deactivated:
|
||||
return "deactivated";
|
||||
case ForceQuitAppMode::Unknown:
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
ForceQuitAppMode toEnum() {
|
||||
if (modeStr == "enabled")
|
||||
return ForceQuitAppMode::Enabled;
|
||||
else if (modeStr == "disabled")
|
||||
return ForceQuitAppMode::Disabled;
|
||||
else if (modeStr == "deactivated")
|
||||
return ForceQuitAppMode::Deactivated;
|
||||
else
|
||||
return ForceQuitAppMode::Unknown;
|
||||
}
|
||||
};
|
||||
|
||||
class Settings;
|
||||
|
||||
// 任务栏组策略配置类
|
||||
class DockSettings: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static inline DockSettings *instance() {
|
||||
static DockSettings instance;
|
||||
return &instance;
|
||||
}
|
||||
void init();
|
||||
|
||||
HideMode getHideMode();
|
||||
void setHideMode(HideMode mode);
|
||||
DisplayMode getDisplayMode();
|
||||
void setDisplayMode(DisplayMode mode);
|
||||
PositonMode getPositionMode();
|
||||
void setPositionMode(PositonMode mode);
|
||||
ForceQuitAppMode getForceQuitAppMode();
|
||||
void setForceQuitAppMode(ForceQuitAppMode mode);
|
||||
uint getIconSize();
|
||||
void setIconSize(uint size);
|
||||
uint getShowTimeout();
|
||||
void setShowTimeout(uint time);
|
||||
uint getHideTimeout();
|
||||
void setHideTimeout(uint time);
|
||||
uint getWindowSizeEfficient();
|
||||
void setWindowSizeEfficient(uint size);
|
||||
uint getWindowSizeFashion();
|
||||
void setWindowSizeFashion(uint size);
|
||||
QStringList getDockedApps();
|
||||
void setDockedApps(QList<QString> &apps);
|
||||
double getOpacity();
|
||||
QVector<QString> getWinIconPreferredApps();
|
||||
|
||||
// plugin settings
|
||||
QString getPluginSettings();
|
||||
void setPluginSettings(QString jsonStr);
|
||||
void mergePluginSettings(QString jsonStr);
|
||||
void removePluginSettings(QString pluginName, QStringList settingkeys);
|
||||
QJsonObject plguinSettingsStrToObj(QString jsonStr);
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
// 隐藏模式改变
|
||||
void hideModeChanged(HideMode mode);
|
||||
// 显示样式改变
|
||||
void displayModeChanged(DisplayMode mode);
|
||||
// 显示位置改变
|
||||
void positionModeChanged(PositonMode mode);
|
||||
// 强制退出应用开关改变
|
||||
void forceQuitAppChanged(bool forced);
|
||||
|
||||
|
||||
private:
|
||||
DockSettings(QObject *paret = nullptr);
|
||||
DockSettings(const DockSettings &);
|
||||
DockSettings& operator= (const DockSettings &);
|
||||
};
|
||||
|
||||
#endif // DOCKSETTINGS_H
|
215
src/modules/dock/entries.cpp
Normal file
215
src/modules/dock/entries.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "entries.h"
|
||||
#include "dock.h"
|
||||
|
||||
Entries::Entries(Dock *_dock)
|
||||
: dock(_dock)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVector<Entry *> Entries::filterDockedEntries()
|
||||
{
|
||||
QVector<Entry *> ret;
|
||||
for (auto &entry : items) {
|
||||
if (entry->isValid() && entry->getIsDocked())
|
||||
ret.push_back(entry);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Entry *Entries::getByInnerId(QString innerId)
|
||||
{
|
||||
Entry *ret = nullptr;
|
||||
for (auto &entry : items) {
|
||||
if (entry->getInnerId() == innerId)
|
||||
ret = entry;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Entries::append(Entry *entry)
|
||||
{
|
||||
insert(entry, -1);
|
||||
}
|
||||
|
||||
void Entries::insert(Entry *entry, int index)
|
||||
{
|
||||
if (index < 0 || index >= items.size()) {
|
||||
// append
|
||||
items.push_back(entry);
|
||||
} else {
|
||||
// insert
|
||||
items.insert(index, entry);
|
||||
}
|
||||
|
||||
insertCb(entry, index);
|
||||
}
|
||||
|
||||
void Entries::remove(Entry *entry)
|
||||
{
|
||||
for (auto iter = items.begin(); iter != items.end(); iter++) {
|
||||
if ((*iter)->getId() == entry->getId()) {
|
||||
items.erase(iter);
|
||||
removeCb(entry);
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Entries::move(int oldIndex, int newIndex)
|
||||
{
|
||||
if (oldIndex == newIndex || oldIndex < 0 || newIndex < 0 || oldIndex >= items.size() || newIndex >= items.size())
|
||||
return;
|
||||
|
||||
items.swap(oldIndex, newIndex);
|
||||
}
|
||||
|
||||
Entry *Entries::getByWindowPid(int pid)
|
||||
{
|
||||
Entry *ret = nullptr;
|
||||
for (auto &entry : items) {
|
||||
if (entry->getWindowInfoByPid(pid)) {
|
||||
ret = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Entry *Entries::getByWindowId(XWindow windowId)
|
||||
{
|
||||
Entry *ret = nullptr;
|
||||
for (auto &entry : items) {
|
||||
if (entry->getWindowInfoByWinId(windowId)) {
|
||||
ret = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Entry *Entries::getByDesktopFilePath(QString filePath)
|
||||
{
|
||||
Entry *ret = nullptr;
|
||||
for (auto &entry : items) {
|
||||
if (entry->getFileName() == filePath) {
|
||||
ret = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList Entries::getEntryIDs()
|
||||
{
|
||||
QStringList list;
|
||||
for (auto item : items)
|
||||
list.push_back(item->getId());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
Entry *Entries::getDockedEntryByDesktopFile(const QString &desktopFile)
|
||||
{
|
||||
Entry *ret = nullptr;
|
||||
for (auto entry : filterDockedEntries()) {
|
||||
if (!entry->isValid())
|
||||
continue;
|
||||
|
||||
if (desktopFile == entry->getFileName()) {
|
||||
ret = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString Entries::queryWindowIdentifyMethod(XWindow windowId)
|
||||
{
|
||||
QString ret;
|
||||
for (auto entry : items) {
|
||||
auto window = entry->getWindowInfoByWinId(windowId);
|
||||
if (window) {
|
||||
auto app = window->getAppInfo();
|
||||
if (app) {
|
||||
ret = app->getIdentifyMethod();
|
||||
} else {
|
||||
ret = "Failed";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Entries::handleActiveWindowChanged(XWindow activeWindId)
|
||||
{
|
||||
for (auto entry : items) {
|
||||
auto windowInfo = entry->getWindowInfoByWinId(activeWindId);
|
||||
if (windowInfo) {
|
||||
entry->setPropIsActive(true);
|
||||
entry->setCurrentWindowInfo(windowInfo);
|
||||
entry->updateName();
|
||||
entry->updateIcon();
|
||||
} else {
|
||||
entry->setPropIsActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Entries::deleteWindow(XWindow xid)
|
||||
{
|
||||
for (auto entry : items) {
|
||||
if (entry->containsWindow(xid)) {
|
||||
entry->deleteWindow(xid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Entries::updateEntriesMenu()
|
||||
{
|
||||
for (auto entry : items) {
|
||||
entry->updateMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void Entries::insertCb(Entry *entry, int index)
|
||||
{
|
||||
QString objPath = entryDBusObjPathPrefix + entry->getId();
|
||||
Q_EMIT dock->entryAdded(objPath, index);
|
||||
}
|
||||
|
||||
void Entries::removeCb(Entry *entry)
|
||||
{
|
||||
Q_EMIT dock->entryRemoved(entry->getId());
|
||||
entry->stopExport();
|
||||
}
|
60
src/modules/dock/entries.h
Normal file
60
src/modules/dock/entries.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ENTRIES_H
|
||||
#define ENTRIES_H
|
||||
|
||||
#include "entry.h"
|
||||
#include <QVector>
|
||||
#include <QWeakPointer>
|
||||
|
||||
class Dock;
|
||||
|
||||
// 所有应用管理类
|
||||
class Entries
|
||||
{
|
||||
public:
|
||||
Entries(Dock *_dock);
|
||||
|
||||
QVector<Entry *> filterDockedEntries();
|
||||
Entry *getByInnerId(QString innerId);
|
||||
void append(Entry *entry);
|
||||
void insert(Entry *entry, int index);
|
||||
void remove(Entry *entry);
|
||||
void move(int oldIndex, int newIndex);
|
||||
Entry *getByWindowPid(int pid);
|
||||
Entry *getByWindowId(XWindow windowId);
|
||||
Entry *getByDesktopFilePath(QString filePath);
|
||||
QStringList getEntryIDs();
|
||||
Entry *getDockedEntryByDesktopFile(const QString &desktopFile);
|
||||
QString queryWindowIdentifyMethod(XWindow windowId);
|
||||
void handleActiveWindowChanged(XWindow activeWindId);
|
||||
void deleteWindow(XWindow xid);
|
||||
void updateEntriesMenu();
|
||||
void insertCb(Entry *entry, int index);
|
||||
void removeCb(Entry *entry);
|
||||
|
||||
private:
|
||||
QList<Entry *> items;
|
||||
Dock *dock;
|
||||
};
|
||||
|
||||
#endif // ENTRIES_H
|
787
src/modules/dock/entry.cpp
Normal file
787
src/modules/dock/entry.cpp
Normal file
@ -0,0 +1,787 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "entry.h"
|
||||
#include "dock.h"
|
||||
#include "processinfo.h"
|
||||
#include "dbusadaptorentry.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDBusInterface>
|
||||
|
||||
#include<signal.h>
|
||||
|
||||
Entry::Entry(Dock *_dock, AppInfo *_app, QString _innerId, QObject *parent)
|
||||
: QObject(parent)
|
||||
, dock(_dock)
|
||||
, app(nullptr)
|
||||
, menu(nullptr)
|
||||
, isActive(false)
|
||||
, isDocked(false)
|
||||
, innerId(_innerId)
|
||||
, current(nullptr)
|
||||
, currentWindow(0)
|
||||
, winIconPreferred(false)
|
||||
{
|
||||
setApp(_app);
|
||||
id = dock->allocEntryId();
|
||||
name = getName();
|
||||
icon = getIcon();
|
||||
}
|
||||
|
||||
Entry::~Entry()
|
||||
{
|
||||
for (auto winInfo : windowInfos) {
|
||||
if (winInfo)
|
||||
delete winInfo;
|
||||
}
|
||||
windowInfos.clear();
|
||||
|
||||
if (app) {
|
||||
delete app;
|
||||
app = nullptr;
|
||||
}
|
||||
|
||||
if (menu) {
|
||||
delete menu;
|
||||
menu = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Entry::isValid()
|
||||
{
|
||||
bool valid = false;
|
||||
if (app)
|
||||
valid = app->isValidApp();
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
QString Entry::getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
QString Entry::getName()
|
||||
{
|
||||
QString ret;
|
||||
if (app)
|
||||
ret = app->getName();
|
||||
|
||||
if (ret.isEmpty() && !!current)
|
||||
ret = current->getDisplayName();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Entry::updateName()
|
||||
{
|
||||
setPropName(getName());
|
||||
}
|
||||
|
||||
QString Entry::getIcon()
|
||||
{
|
||||
QString ret;
|
||||
if (hasWindow()) {
|
||||
if (!current)
|
||||
return ret;
|
||||
|
||||
// has window && current not nullptr
|
||||
if (winIconPreferred) {
|
||||
// try current window icon first
|
||||
ret = current->getIcon();
|
||||
if (ret.size() > 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (app) {
|
||||
icon = app->getIcon();
|
||||
if (icon.size() > 0)
|
||||
return ret;
|
||||
}
|
||||
ret = current->getIcon();
|
||||
} else if (app) {
|
||||
// no window
|
||||
ret = app->getIcon();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString Entry::getInnerId()
|
||||
{
|
||||
return innerId;
|
||||
}
|
||||
|
||||
void Entry::setInnerId(QString _innerId)
|
||||
{
|
||||
innerId = _innerId;
|
||||
}
|
||||
|
||||
QString Entry::getFileName()
|
||||
{
|
||||
QString fileName;
|
||||
if (app)
|
||||
fileName = app->getFileName();
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
AppInfo *Entry::getApp()
|
||||
{
|
||||
return app;
|
||||
}
|
||||
|
||||
void Entry::setApp(AppInfo *appinfo)
|
||||
{
|
||||
if (app == appinfo)
|
||||
return;
|
||||
|
||||
if (app)
|
||||
delete app;
|
||||
|
||||
app = appinfo;
|
||||
if (!appinfo) {
|
||||
winIconPreferred = true;
|
||||
setPropDesktopFile("");
|
||||
} else {
|
||||
winIconPreferred = false;
|
||||
setPropDesktopFile(appinfo->getFileName());
|
||||
QString id = app->getId();
|
||||
auto perferredApps = dock->getWinIconPreferredApps();
|
||||
if (perferredApps.contains(id)) {
|
||||
winIconPreferred = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (appinfo->getIcon().size() == 0) {
|
||||
winIconPreferred = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Entry::getIsDocked()
|
||||
{
|
||||
return isDocked;
|
||||
}
|
||||
|
||||
void Entry::setIsDocked(bool value)
|
||||
{
|
||||
if (value != isDocked) {
|
||||
isDocked = value;
|
||||
Q_EMIT isDockedChanged(value);
|
||||
}
|
||||
}
|
||||
|
||||
// 导出Dbus服务
|
||||
void Entry::startExport()
|
||||
{
|
||||
if (getId().isEmpty()) {
|
||||
qWarning() << "startExport Entry " << getName() << " id is Empty";
|
||||
return;
|
||||
}
|
||||
|
||||
new DBusAdaptorEntry(this); // export dbus by Adaptor
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
if (!con.registerService(dbusService)) {
|
||||
qWarning() << "register service Dock1 error:" << con.lastError().message();
|
||||
return;
|
||||
}
|
||||
|
||||
objctPath = entryDBusObjPathPrefix + getId();
|
||||
if (!con.registerObject(objctPath, this))
|
||||
{
|
||||
qWarning() << "register object Dock1 error:" << con.lastError().message();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 停止导出Dbus服务
|
||||
void Entry::stopExport()
|
||||
{
|
||||
if (getId().isEmpty()) {
|
||||
qWarning() << "stopExport Entry " << getName() << " id is Empty";
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
objctPath.clear();
|
||||
con.unregisterObject(entryDBusObjPathPrefix + getId());
|
||||
}
|
||||
|
||||
void Entry::setMenu(AppMenu *_menu)
|
||||
{
|
||||
_menu->setDirtyStatus(true);
|
||||
if (menu)
|
||||
delete menu;
|
||||
|
||||
menu = _menu;
|
||||
Q_EMIT menuChanged(menu->getMenuJsonStr());
|
||||
}
|
||||
|
||||
void Entry::updateMenu()
|
||||
{
|
||||
qInfo() <<"Entry: updateMenu";
|
||||
AppMenu *appMenu = new AppMenu();
|
||||
appMenu->appendItem(getMenuItemLaunch());
|
||||
|
||||
for (auto &item :getMenuItemDesktopActions())
|
||||
appMenu->appendItem(item);
|
||||
|
||||
bool hasWin = hasWindow();
|
||||
if (hasWin)
|
||||
appMenu->appendItem(getMenuItemAllWindows());
|
||||
|
||||
// menu item dock or undock
|
||||
qInfo() << "entry " << id << " docked? " << isDocked;
|
||||
if (isDocked)
|
||||
appMenu->appendItem(getMenuItemUndock());
|
||||
else
|
||||
appMenu->appendItem(getMenuItemDock());
|
||||
|
||||
if (hasWindow()) {
|
||||
if (dock->getForceQuitAppStatus() != ForceQuitAppMode::Disabled) {
|
||||
if (app && app->getIdentifyMethod() == "Andriod")
|
||||
appMenu->appendItem(getMenuItemForceQuitAndroid());
|
||||
else
|
||||
appMenu->appendItem(getMenuItemForceQuit());
|
||||
}
|
||||
|
||||
if (getAllowedCloseWindows().size() > 0)
|
||||
appMenu->appendItem(getMenuItemCloseAll());
|
||||
}
|
||||
setMenu(appMenu);
|
||||
}
|
||||
|
||||
void Entry::updateIcon()
|
||||
{
|
||||
setPropIcon(getIcon());
|
||||
}
|
||||
|
||||
void Entry::forceUpdateIcon()
|
||||
{
|
||||
icon = getIcon();
|
||||
Q_EMIT iconChanged(icon);
|
||||
}
|
||||
|
||||
void Entry::updateIsActive()
|
||||
{
|
||||
bool isActive = false;
|
||||
auto activeWin = dock->getActiveWindow();
|
||||
if (activeWin)
|
||||
isActive = windowInfos.find(activeWin->getXid()) != windowInfos.end();
|
||||
|
||||
setPropIsActive(isActive);
|
||||
}
|
||||
|
||||
WindowInfoBase *Entry::getWindowInfoByPid(int pid)
|
||||
{
|
||||
WindowInfoBase *ret = nullptr;
|
||||
for (const auto &windowInfo : windowInfos) {
|
||||
if (windowInfo->getPid() == pid) {
|
||||
ret = windowInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WindowInfoBase *Entry::getWindowInfoByWinId(XWindow windowId)
|
||||
{
|
||||
WindowInfoBase *ret = nullptr;
|
||||
if (windowInfos.find(windowId) != windowInfos.end()) {
|
||||
ret = windowInfos[windowId];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Entry::setPropIsDocked(bool docked)
|
||||
{
|
||||
if (isDocked != docked) {
|
||||
isDocked = docked;
|
||||
Q_EMIT isDockedChanged(docked);
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::setPropIcon(QString value)
|
||||
{
|
||||
if (value != icon) {
|
||||
icon = value;
|
||||
Q_EMIT iconChanged(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::setPropName(QString value)
|
||||
{
|
||||
if (value != name) {
|
||||
name = value;
|
||||
Q_EMIT nameChanged(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::setPropIsActive(bool active)
|
||||
{
|
||||
if (isActive != active) {
|
||||
isActive = active;
|
||||
Q_EMIT isActiveChanged(active);
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::setCurrentWindowInfo(WindowInfoBase *windowInfo)
|
||||
{
|
||||
current = windowInfo;
|
||||
setPropCurrentWindow(current ? current->getXid() : 0);
|
||||
}
|
||||
|
||||
void Entry::setPropCurrentWindow(XWindow value)
|
||||
{
|
||||
if (value != currentWindow) {
|
||||
currentWindow = value;
|
||||
Q_EMIT currentWindowChanged(value);
|
||||
}
|
||||
}
|
||||
|
||||
WindowInfoBase *Entry::getCurrentWindowInfo()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
QString Entry::getExec(bool oneLine)
|
||||
{
|
||||
QString ret;
|
||||
if (!current)
|
||||
return ret;
|
||||
|
||||
ProcessInfo *process = current->getProcess();
|
||||
if (process) {
|
||||
if (oneLine)
|
||||
ret = process->getOneCommandLine().c_str();
|
||||
else
|
||||
ret = process->getShellScriptLines().c_str();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Entry::hasWindow()
|
||||
{
|
||||
return windowInfos.size() > 0;
|
||||
}
|
||||
|
||||
void Entry::updateWindowInfos()
|
||||
{
|
||||
QList<ExportWindowInfo> infos;
|
||||
bool changed = false;
|
||||
for (auto info : windowInfos) {
|
||||
XWindow xid = info->getXid();
|
||||
QString title = info->getTitle();
|
||||
bool flash = info->isDemandingAttention();
|
||||
infos.push_back({xid, title, flash});
|
||||
if (!changed) {
|
||||
for (auto info : exportWindowInfos) {
|
||||
if (info.title != title || info.flash != flash)
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
exportWindowInfos = infos;
|
||||
}
|
||||
}
|
||||
|
||||
// 分离窗口, 返回是否需要从任务栏remove
|
||||
bool Entry::detachWindow(WindowInfoBase *info)
|
||||
{
|
||||
info->setEntry(nullptr);
|
||||
XWindow winId = info->getXid();
|
||||
deleteWindow(winId);
|
||||
|
||||
if (windowInfos.size() == 0) {
|
||||
if (!isDocked) // 既无窗口也非驻留应用,无需在任务栏显示
|
||||
return true;
|
||||
|
||||
setCurrentWindowInfo(nullptr);
|
||||
} else {
|
||||
for (auto window : windowInfos) {
|
||||
if (window) { // 选择第一个窗口作为当前窗口
|
||||
setCurrentWindowInfo(window);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateWindowInfos();
|
||||
updateIcon();
|
||||
updateIsActive();
|
||||
updateMenu();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Entry::attachWindow(WindowInfoBase *info)
|
||||
{
|
||||
XWindow winId = info->getXid();
|
||||
qInfo() << "attatchWindow: window id:" << winId;
|
||||
info->setEntry(this);
|
||||
|
||||
if (windowInfos.find(winId) != windowInfos.end()) {
|
||||
qInfo() << "attachWindow: window " << winId << " is already attached";
|
||||
return false;
|
||||
}
|
||||
|
||||
windowInfos[winId] = info;
|
||||
updateWindowInfos();
|
||||
updateIsActive();
|
||||
|
||||
if (!current) {
|
||||
// from no window to has window
|
||||
setCurrentWindowInfo(info);
|
||||
}
|
||||
|
||||
updateIcon();
|
||||
updateMenu();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Entry::launchApp(uint32_t timestamp)
|
||||
{
|
||||
dock->launchApp(timestamp, QStringList() << app->getFileName());
|
||||
}
|
||||
|
||||
bool Entry::containsWindow(XWindow xid)
|
||||
{
|
||||
return windowInfos.find(xid) != windowInfos.end();
|
||||
}
|
||||
|
||||
void Entry::deleteWindow(XWindow xid)
|
||||
{
|
||||
WindowInfoBase *info = windowInfos[xid];
|
||||
windowInfos.remove(xid);
|
||||
for (int i = 0; i < exportWindowInfos.size(); i++) {
|
||||
if (exportWindowInfos[i].xid == xid) {
|
||||
exportWindowInfos.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (info) {
|
||||
delete info;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理菜单项
|
||||
void Entry::handleMenuItem(uint32_t timestamp, QString itemId)
|
||||
{
|
||||
menu->handleAction(timestamp, itemId);
|
||||
}
|
||||
|
||||
// 处理拖拽事件
|
||||
void Entry::handleDragDrop(uint32_t timestamp, QStringList files)
|
||||
{
|
||||
dock->launchApp(timestamp, files);
|
||||
}
|
||||
|
||||
// 驻留
|
||||
void Entry::requestDock()
|
||||
{
|
||||
if (dock->dockEntry(this)) {
|
||||
dock->saveDockedApps();
|
||||
}
|
||||
}
|
||||
|
||||
// 取消驻留
|
||||
void Entry::requestUndock()
|
||||
{
|
||||
dock->undockEntry(this);
|
||||
}
|
||||
|
||||
void Entry::newInstance(uint32_t timestamp)
|
||||
{
|
||||
QStringList files;
|
||||
dock->launchApp(timestamp, files);
|
||||
}
|
||||
|
||||
// 检查应用窗口分离、合并状态
|
||||
void Entry::check()
|
||||
{
|
||||
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) {
|
||||
dock->attachOrDetachWindow(iter.value());
|
||||
}
|
||||
}
|
||||
|
||||
// 强制退出
|
||||
void Entry::forceQuit()
|
||||
{
|
||||
QMap<int, QVector<WindowInfoBase*>> pidWinInfoMap;
|
||||
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) {
|
||||
int pid = iter.value()->getPid();
|
||||
if (pid != 0) {
|
||||
pidWinInfoMap[pid].push_back(iter.value());
|
||||
} else {
|
||||
iter.value()->killClient();
|
||||
}
|
||||
|
||||
for (auto iter = pidWinInfoMap.begin(); iter != pidWinInfoMap.end(); iter++) {
|
||||
if (!killProcess(iter.key())) { // kill pid
|
||||
for (auto &info : iter.value()) { // kill window
|
||||
info->killClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::presentWindows()
|
||||
{
|
||||
QList<uint> windows;
|
||||
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++)
|
||||
windows.push_back(iter.key());
|
||||
|
||||
dock->presentWindows(windows);
|
||||
}
|
||||
|
||||
void Entry::active(uint32_t timestamp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
XWindow Entry::getCurrentWindow()
|
||||
{
|
||||
return currentWindow;
|
||||
}
|
||||
|
||||
QString Entry::getDesktopFile()
|
||||
{
|
||||
return desktopFile;
|
||||
}
|
||||
|
||||
bool Entry::getIsActive()
|
||||
{
|
||||
return isActive;
|
||||
}
|
||||
|
||||
QString Entry::getMenu()
|
||||
{
|
||||
return menu->getMenuJsonStr();
|
||||
}
|
||||
|
||||
QVector<XWindow> Entry::getAllowedClosedWindowIds()
|
||||
{
|
||||
QVector<XWindow> ret;
|
||||
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) {
|
||||
WindowInfoBase *info = iter.value();
|
||||
if (info && info->allowClose())
|
||||
ret.push_back(iter.key());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<ExportWindowInfo> Entry::getExportWindowInfos()
|
||||
{
|
||||
return exportWindowInfos;
|
||||
}
|
||||
|
||||
QVector<WindowInfoBase *> Entry::getAllowedCloseWindows()
|
||||
{
|
||||
QVector<WindowInfoBase *> ret;
|
||||
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) {
|
||||
WindowInfoBase *info = iter.value();
|
||||
if (info && info->allowClose())
|
||||
ret.push_back(info);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVector<AppMenuItem> Entry::getMenuItemDesktopActions()
|
||||
{
|
||||
QVector<AppMenuItem> ret;
|
||||
if (!app)
|
||||
return ret;
|
||||
|
||||
for (auto action : app->getActions()) {
|
||||
AppMenuAction fn = [&](uint32_t timestamp) {
|
||||
qInfo() << "do MenuItem: " << action.name.c_str();
|
||||
dock->launchAppAction(timestamp, app->getFileName(), action.section.c_str());
|
||||
};
|
||||
|
||||
AppMenuItem item;
|
||||
item.text = action.name.c_str();
|
||||
item.action = fn;
|
||||
item.isActive = true;
|
||||
ret.push_back(item);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppMenuItem Entry::getMenuItemLaunch()
|
||||
{
|
||||
QString itemName;
|
||||
if (hasWindow())
|
||||
itemName = getName();
|
||||
else
|
||||
itemName = "Open";
|
||||
|
||||
AppMenuAction fn = [&](uint32_t timestamp) {
|
||||
qInfo() << "do MenuItem: Open";
|
||||
this->launchApp(timestamp);
|
||||
};
|
||||
|
||||
AppMenuItem item;
|
||||
item.text = itemName;
|
||||
item.action = fn;
|
||||
item.isActive = true;
|
||||
return item;
|
||||
}
|
||||
|
||||
AppMenuItem Entry::getMenuItemCloseAll()
|
||||
{
|
||||
AppMenuAction fn = [&](uint32_t timestamp) {
|
||||
qInfo() << "do MenuItem: Close All";
|
||||
auto winInfos = getAllowedCloseWindows();
|
||||
|
||||
// 从大到小排序, 方便后面关闭窗口
|
||||
for (int i = 0; i < winInfos.size() - 1; i++) {
|
||||
for (int j = i + 1; j < winInfos.size(); j++) {
|
||||
if (winInfos[i]->getCreatedTime() < winInfos[j]->getCreatedTime()) {
|
||||
auto info = winInfos[i];
|
||||
winInfos[i] = winInfos[j];
|
||||
winInfos[j] = info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto info : winInfos) {
|
||||
qInfo() << "close WindowId " << info->getXid();
|
||||
info->close(timestamp);
|
||||
}
|
||||
};
|
||||
|
||||
AppMenuItem item;
|
||||
item.text = "Close All";
|
||||
item.action = fn;
|
||||
item.isActive = true;
|
||||
return item;
|
||||
}
|
||||
|
||||
AppMenuItem Entry::getMenuItemForceQuit()
|
||||
{
|
||||
bool active = dock->getForceQuitAppStatus() != ForceQuitAppMode::Deactivated;
|
||||
AppMenuAction fn = [&](uint32_t) {
|
||||
qInfo() << "do MenuItem: Force Quit";
|
||||
forceQuit();
|
||||
};
|
||||
|
||||
AppMenuItem item;
|
||||
item.text = "Force Quit";
|
||||
item.action = fn;
|
||||
item.isActive = active;
|
||||
return item;
|
||||
}
|
||||
|
||||
//dock栏上Android程序的Force Quit功能
|
||||
AppMenuItem Entry::getMenuItemForceQuitAndroid()
|
||||
{
|
||||
bool active = dock->getForceQuitAppStatus() != ForceQuitAppMode::Deactivated;
|
||||
auto allowedCloseWindows = getAllowedCloseWindows();
|
||||
AppMenuAction fn = [](uint32_t){};
|
||||
if (allowedCloseWindows.size() > 0) {
|
||||
qInfo() << "do MenuItem: Force Quit";
|
||||
AppMenuAction fn = [&](uint32_t timestamp) {
|
||||
for (auto info : allowedCloseWindows) {
|
||||
info->close(timestamp);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
AppMenuItem item;
|
||||
item.text = "Force Quit";
|
||||
item.action = fn;
|
||||
item.isActive = active;
|
||||
return item;
|
||||
}
|
||||
|
||||
AppMenuItem Entry::getMenuItemDock()
|
||||
{
|
||||
AppMenuItem item;
|
||||
item.text = "Dock";
|
||||
item.action = [&](uint32_t) {
|
||||
qInfo() << "do MenuItem: Dock";
|
||||
requestDock();
|
||||
};
|
||||
item.isActive = true;
|
||||
return item;
|
||||
}
|
||||
|
||||
AppMenuItem Entry::getMenuItemUndock()
|
||||
{
|
||||
AppMenuItem item;
|
||||
item.text = "Undock";
|
||||
item.action = [&](uint32_t) {
|
||||
qInfo() << "do MenuItem: Undock";
|
||||
requestUndock();
|
||||
};
|
||||
item.isActive = true;
|
||||
return item;
|
||||
}
|
||||
|
||||
AppMenuItem Entry::getMenuItemAllWindows()
|
||||
{
|
||||
AppMenuItem item;
|
||||
item.text = "All Windows";
|
||||
item.action = [&](uint32_t) {
|
||||
qInfo() << "do MenuItem: All Windows";
|
||||
presentWindows();
|
||||
};
|
||||
item.isActive = true;
|
||||
item.hint = menuItemHintShowAllWindows;
|
||||
return item;
|
||||
}
|
||||
|
||||
bool Entry::killProcess(int pid)
|
||||
{
|
||||
bool ret = true;
|
||||
Process p(pid);
|
||||
if (p.isExist()) {
|
||||
ret = !kill(pid, SIGTERM);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Entry::setPropDesktopFile(QString value)
|
||||
{
|
||||
bool ret = false;
|
||||
if (value != desktopFile) {
|
||||
desktopFile = value;
|
||||
ret = true;
|
||||
Q_EMIT desktopFileChanged(value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
149
src/modules/dock/entry.h
Normal file
149
src/modules/dock/entry.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ENTRY_H
|
||||
#define ENTRY_H
|
||||
|
||||
#include "appinfo.h"
|
||||
#include "appmenu.h"
|
||||
#include "windowinfobase.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QVector>
|
||||
#include <QObject>
|
||||
|
||||
struct ExportWindowInfo {
|
||||
XWindow xid;
|
||||
QString title;
|
||||
bool flash;
|
||||
};
|
||||
|
||||
// 单个应用类
|
||||
class Dock;
|
||||
class Entry: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Entry(Dock *_dock, AppInfo *_app, QString _innerId, QObject *parent = nullptr);
|
||||
~Entry();
|
||||
|
||||
bool isValid();
|
||||
QString getId();
|
||||
QString getName();
|
||||
void updateName();
|
||||
QString getIcon();
|
||||
QString getInnerId();
|
||||
void setInnerId(QString _innerId);
|
||||
QString getFileName();
|
||||
AppInfo *getApp();
|
||||
void setApp(AppInfo *appinfo);
|
||||
bool getIsDocked();
|
||||
void setIsDocked(bool value);
|
||||
void startExport();
|
||||
void stopExport();
|
||||
void setMenu(AppMenu *_menu);
|
||||
void updateMenu();
|
||||
void updateIcon();
|
||||
void forceUpdateIcon();
|
||||
void updateIsActive();
|
||||
WindowInfoBase *getWindowInfoByPid(int pid);
|
||||
WindowInfoBase *getWindowInfoByWinId(XWindow windowId);
|
||||
void setPropIsDocked(bool docked);
|
||||
void setPropIcon(QString value);
|
||||
void setPropName(QString value);
|
||||
void setPropIsActive(bool active);
|
||||
void setPropCurrentWindow(XWindow value);
|
||||
void setCurrentWindowInfo(WindowInfoBase *windowInfo);
|
||||
WindowInfoBase *getCurrentWindowInfo();
|
||||
QString getExec(bool oneLine);
|
||||
bool hasWindow();
|
||||
void updateWindowInfos();
|
||||
bool detachWindow(WindowInfoBase *info);
|
||||
bool attachWindow(WindowInfoBase *info);
|
||||
void launchApp(uint32_t timestamp);
|
||||
bool containsWindow(XWindow xid);
|
||||
void deleteWindow(XWindow xid);
|
||||
|
||||
void handleMenuItem(uint32_t timestamp, QString itemId);
|
||||
void handleDragDrop(uint32_t timestamp, QStringList files);
|
||||
void requestDock();
|
||||
void requestUndock();
|
||||
void newInstance(uint32_t timestamp);
|
||||
void check();
|
||||
void forceQuit();
|
||||
void presentWindows();
|
||||
void active(uint32_t timestamp);
|
||||
|
||||
XWindow getCurrentWindow();
|
||||
QString getDesktopFile();
|
||||
bool getIsActive();
|
||||
QString getMenu();
|
||||
QVector<XWindow> getAllowedClosedWindowIds();
|
||||
QList<ExportWindowInfo> getExportWindowInfos();
|
||||
|
||||
public Q_SLOTS:
|
||||
QVector<WindowInfoBase *> getAllowedCloseWindows();
|
||||
|
||||
Q_SIGNALS:
|
||||
void isActiveChanged(bool value);
|
||||
void isDockedChanged(bool value);
|
||||
void menuChanged(QString value);
|
||||
void iconChanged(QString value);
|
||||
void nameChanged(QString value);
|
||||
void desktopFileChanged(QString value);
|
||||
void currentWindowChanged(uint32_t value);
|
||||
|
||||
private:
|
||||
// 右键菜单项
|
||||
QVector<AppMenuItem> getMenuItemDesktopActions();
|
||||
AppMenuItem getMenuItemLaunch();
|
||||
AppMenuItem getMenuItemCloseAll();
|
||||
AppMenuItem getMenuItemForceQuit();
|
||||
AppMenuItem getMenuItemForceQuitAndroid();
|
||||
AppMenuItem getMenuItemDock();
|
||||
AppMenuItem getMenuItemUndock();
|
||||
AppMenuItem getMenuItemAllWindows();
|
||||
bool killProcess(int pid);
|
||||
bool setPropDesktopFile(QString value);
|
||||
|
||||
Dock *dock;
|
||||
AppInfo *app;
|
||||
AppMenu *menu;
|
||||
|
||||
bool isActive;
|
||||
bool isDocked;
|
||||
|
||||
QString id;
|
||||
QString name;
|
||||
QString icon;
|
||||
QString innerId;
|
||||
QString desktopFile;
|
||||
|
||||
// Dbus属性直接放到interface上
|
||||
QMap<XWindow, WindowInfoBase *> windowInfos; // 该应用所有窗口
|
||||
QList<ExportWindowInfo> exportWindowInfos;
|
||||
WindowInfoBase *current; // 当前窗口
|
||||
XWindow currentWindow; //当前窗口Id
|
||||
bool winIconPreferred;
|
||||
QString objctPath;
|
||||
};
|
||||
|
||||
#endif // ENTRY_H
|
141
src/modules/dock/processinfo.cpp
Normal file
141
src/modules/dock/processinfo.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "processinfo.h"
|
||||
#include "dstring.h"
|
||||
#include "dfile.h"
|
||||
|
||||
ProcessInfo::ProcessInfo(int pid)
|
||||
: hasPid(true)
|
||||
, process(Process(pid))
|
||||
{
|
||||
if (pid == 0)
|
||||
return;
|
||||
|
||||
// exe
|
||||
exe = process.getExe();
|
||||
// cwd
|
||||
cwd = process.getCwd();
|
||||
// cmdline
|
||||
cmdLine = process.getCmdLine();
|
||||
// ppid
|
||||
Status pstatus = process.getStatus();
|
||||
if (pstatus.size() > 0) {
|
||||
int ppid = process.getPpid();
|
||||
}
|
||||
// args
|
||||
auto verifyExe = [](std::string exe, std::string cwd, std::string firstArg){
|
||||
if (DFile::base(firstArg) == firstArg)
|
||||
return true;
|
||||
|
||||
if (!DFile::isAbs(firstArg))
|
||||
firstArg = cwd + firstArg;
|
||||
|
||||
return exe == firstArg;
|
||||
};
|
||||
if (!verifyExe(exe, cwd, cmdLine[0])) {
|
||||
auto parts = DString::splitStr(cmdLine[0], ' ');
|
||||
// try again
|
||||
if (verifyExe(exe, cwd, parts[0])) {
|
||||
for (int j = 1; j < parts.size(); j++) {
|
||||
args.push_back(parts[j]);
|
||||
}
|
||||
for (int i = 1; i < cmdLine.size(); i++) {
|
||||
args.push_back(cmdLine[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < cmdLine.size(); i++) {
|
||||
args.push_back(cmdLine[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProcessInfo::ProcessInfo(std::vector<std::string> &cmd)
|
||||
: hasPid(false)
|
||||
, process(Process())
|
||||
{
|
||||
if (cmd.size() == 0)
|
||||
return;
|
||||
|
||||
cmdLine = cmd;
|
||||
exe = cmd[0];
|
||||
for (ulong i=0; i < cmd.size(); i++) {
|
||||
if (i > 0) {
|
||||
args.push_back(cmd[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ProcessInfo::getEnv(std::string key)
|
||||
{
|
||||
return process.getEnv(key);
|
||||
}
|
||||
|
||||
std::vector<std::string> ProcessInfo::getCmdLine()
|
||||
{
|
||||
return cmdLine;
|
||||
}
|
||||
|
||||
std::vector<std::string> ProcessInfo::getArgs()
|
||||
{
|
||||
return args;
|
||||
}
|
||||
|
||||
int ProcessInfo::getPid()
|
||||
{
|
||||
return process.getPid();
|
||||
}
|
||||
|
||||
int ProcessInfo::getPpid()
|
||||
{
|
||||
return process.getPpid();
|
||||
}
|
||||
|
||||
std::string ProcessInfo::getExe()
|
||||
{
|
||||
return exe;
|
||||
}
|
||||
|
||||
std::string ProcessInfo::getOneCommandLine()
|
||||
{
|
||||
std::string cmdline = getJoinedExeArgs();
|
||||
return "sh -c 'cd " + cwd + "; exec " + cmdline + ";'";
|
||||
}
|
||||
|
||||
std::string ProcessInfo::getShellScriptLines()
|
||||
{
|
||||
std::string cmdline = getJoinedExeArgs();
|
||||
return "#!/bin/sh\n cd " + cwd + "\n exec " + cmdline + "\n";
|
||||
}
|
||||
|
||||
std::string ProcessInfo::getJoinedExeArgs()
|
||||
{
|
||||
std::string ret = "\"" + exe + "\"";
|
||||
for (auto arg : args) {
|
||||
ret += " \"" + arg + "\"";
|
||||
}
|
||||
|
||||
ret += " $@";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
58
src/modules/dock/processinfo.h
Normal file
58
src/modules/dock/processinfo.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESSINFO_H
|
||||
#define PROCESSINFO_H
|
||||
|
||||
#include "process.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// 进程信息
|
||||
class ProcessInfo
|
||||
{
|
||||
public:
|
||||
ProcessInfo(int pid);
|
||||
ProcessInfo(std::vector<std::string> &cmd);
|
||||
|
||||
std::string getEnv(std::string key);
|
||||
std::vector<std::string> getCmdLine();
|
||||
std::vector<std::string> getArgs();
|
||||
int getPid();
|
||||
int getPpid();
|
||||
std::string getExe();
|
||||
std::string getOneCommandLine();
|
||||
std::string getShellScriptLines();
|
||||
|
||||
private:
|
||||
std::string getJoinedExeArgs();
|
||||
|
||||
std::vector<std::string> cmdLine;
|
||||
std::vector<std::string> args;
|
||||
std::string exe;
|
||||
std::string cwd;
|
||||
|
||||
bool hasPid;
|
||||
Process process;
|
||||
};
|
||||
|
||||
#endif // PROCESSINFO_H
|
127
src/modules/dock/waylandmanager.cpp
Normal file
127
src/modules/dock/waylandmanager.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "waylandmanager.h"
|
||||
#include "dock.h"
|
||||
#include "xcbutils.h"
|
||||
|
||||
#define XCB XCBUtils::instance()
|
||||
|
||||
WaylandManager::WaylandManager(Dock *_dock, QObject *parent)
|
||||
: QObject(parent)
|
||||
, dock(_dock)
|
||||
, mutex(QMutex(QMutex::NonRecursive))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 注册窗口
|
||||
void WaylandManager::registerWindow(const QString &objPath)
|
||||
{
|
||||
qInfo() << "registerWindow: " << objPath;
|
||||
if (findWindowByObjPath(objPath))
|
||||
return;
|
||||
|
||||
PlasmaWindow *plasmaWindow = dock->createPlasmaWindow(objPath);
|
||||
if (!plasmaWindow) {
|
||||
qWarning() << "registerWindowWayland: createPlasmaWindow failed";
|
||||
return;
|
||||
}
|
||||
|
||||
QString appId = plasmaWindow->AppId();
|
||||
QStringList list {"dde-dock", "dde-launcher", "dde-clipboard", "dde-osd", "dde-polkit-agent", "dde-simple-egl", "dmcs"};
|
||||
if (list.indexOf(appId))
|
||||
return;
|
||||
|
||||
XWindow winId = XCB->allocId(); // XCB中未发现释放XID接口
|
||||
XWindow realId = plasmaWindow->WindowId();
|
||||
if (!realId)
|
||||
winId = realId;
|
||||
|
||||
WindowInfoK *winInfo = new WindowInfoK(plasmaWindow, winId);
|
||||
dock->listenKWindowSignals(winInfo);
|
||||
insertWindow(objPath, winInfo);
|
||||
dock->attachOrDetachWindow(winInfo);
|
||||
if (realId) {
|
||||
windowInfoMap[realId] = winInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// 取消注册窗口
|
||||
void WaylandManager::unRegisterWindow(const QString &objPath)
|
||||
{
|
||||
qInfo() << "unRegisterWindow: " << objPath;
|
||||
WindowInfoK *winInfo = findWindowByObjPath(objPath);
|
||||
if (!winInfo)
|
||||
return;
|
||||
|
||||
dock->removePlasmaWindowHandler(winInfo->getPlasmaWindow());
|
||||
dock->detachWindow(winInfo);
|
||||
deleteWindow(objPath);
|
||||
}
|
||||
|
||||
WindowInfoK *WaylandManager::handleActiveWindowChangedK(uint activeWin)
|
||||
{
|
||||
WindowInfoK *winInfo = nullptr;
|
||||
QMutexLocker locker(&mutex);
|
||||
for (auto iter = kWinInfos.begin(); iter != kWinInfos.end(); iter++) {
|
||||
if (iter.value()->getInnerId() == activeWin) {
|
||||
winInfo = iter.value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return winInfo;
|
||||
}
|
||||
|
||||
WindowInfoK *WaylandManager::findWindowByXid(XWindow xid)
|
||||
{
|
||||
WindowInfoK *winInfo = nullptr;
|
||||
for (auto iter = kWinInfos.begin(); iter != kWinInfos.end(); iter++) {
|
||||
if (iter.value()->getXid() == xid) {
|
||||
winInfo = iter.value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return winInfo;
|
||||
}
|
||||
|
||||
WindowInfoK *WaylandManager::findWindowByObjPath(QString objPath)
|
||||
{
|
||||
if (kWinInfos.find(objPath) == kWinInfos.end())
|
||||
return nullptr;
|
||||
|
||||
return kWinInfos[objPath];
|
||||
}
|
||||
|
||||
void WaylandManager::insertWindow(QString objPath, WindowInfoK *windowInfo)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
kWinInfos[objPath] = windowInfo;
|
||||
}
|
||||
|
||||
void WaylandManager::deleteWindow(QString objPath)
|
||||
{
|
||||
kWinInfos.remove(objPath);
|
||||
}
|
||||
|
56
src/modules/dock/waylandmanager.h
Normal file
56
src/modules/dock/waylandmanager.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WAYLANDMANAGER_H
|
||||
#define WAYLANDMANAGER_H
|
||||
|
||||
#include "windowinfok.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
|
||||
class Dock;
|
||||
|
||||
// 管理wayland窗口
|
||||
class WaylandManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WaylandManager(Dock *_dock, QObject *parent = nullptr);
|
||||
|
||||
void registerWindow(const QString &objPath);
|
||||
void unRegisterWindow(const QString &objPath);
|
||||
|
||||
WindowInfoK *handleActiveWindowChangedK(uint activeWin);
|
||||
WindowInfoK *findWindowByXid(XWindow xid);
|
||||
WindowInfoK *findWindowByObjPath(QString objPath);
|
||||
void insertWindow(QString objPath, WindowInfoK *windowInfo);
|
||||
void deleteWindow(QString objPath);
|
||||
|
||||
private:
|
||||
Dock *dock;
|
||||
QMap<QString, WindowInfoK *> kWinInfos; // dbusObjectPath -> kwayland window Info
|
||||
QMap<XWindow, WindowInfoK *> windowInfoMap;
|
||||
QMutex mutex;
|
||||
};
|
||||
|
||||
#endif // WAYLANDMANAGER_H
|
545
src/modules/dock/windowidentify.cpp
Normal file
545
src/modules/dock/windowidentify.cpp
Normal file
@ -0,0 +1,545 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "windowidentify.h"
|
||||
#include "common.h"
|
||||
#include "appinfo.h"
|
||||
#include "dock.h"
|
||||
#include "processinfo.h"
|
||||
#include "dstring.h"
|
||||
#include "basedir.h"
|
||||
#include "dfile.h"
|
||||
#include "xcbutils.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QThread>
|
||||
|
||||
#define XCB XCBUtils::instance()
|
||||
|
||||
WindowPatterns WindowIdentify::patterns;
|
||||
|
||||
static QMap<QString, QString> crxAppIdMap = {
|
||||
{"crx_onfalgmmmaighfmjgegnamdjmhpjpgpi", "apps.com.aiqiyi"},
|
||||
{"crx_gfhkopakpiiaeocgofdpcpjpdiglpkjl", "apps.cn.kugou.hd"},
|
||||
{"crx_gaoopbnflngfkoobibfgbhobdeiipcgh", "apps.cn.kuwo.kwmusic"},
|
||||
{"crx_jajaphleehpmpblokgighfjneejapnok", "apps.com.evernote"},
|
||||
{"crx_ebhffdbfjilfhahiinoijchmlceailfn", "apps.com.letv"},
|
||||
{"crx_almpoflgiciaanepplakjdkiaijmklld", "apps.com.tongyong.xxbox"},
|
||||
{"crx_heaphplipeblmpflpdcedfllmbehonfo", "apps.com.peashooter"},
|
||||
{"crx_dbngidmdhcooejaggjiochbafiaefndn", "apps.com.rovio.angrybirdsseasons"},
|
||||
{"crx_chfeacahlaknlmjhiagghobhkollfhip", "apps.com.sina.weibo"},
|
||||
{"crx_cpbmecbkmjjfemjiekledmejoakfkpec", "apps.com.openapp"},
|
||||
{"crx_lalomppgkdieklbppclocckjpibnlpjc", "apps.com.baidutieba"},
|
||||
{"crx_gejbkhjjmicgnhcdpgpggboldigfhgli", "apps.com.zhuishushenqi"},
|
||||
{"crx_gglenfcpioacendmikabbkecnfpanegk", "apps.com.duokan"},
|
||||
{"crx_nkmmgdfgabhefacpfdabadjfnpffhpio", "apps.com.zhihu.daily"},
|
||||
{"crx_ajkogonhhcighbinfgcgnjiadodpdicb", "apps.com.netease.newsreader"},
|
||||
{"crx_hgggjnaaklhemplabjhgpodlcnndhppo", "apps.com.baidu.music.pad"},
|
||||
{"crx_ebmgfebnlgilhandilnbmgadajhkkmob", "apps.cn.ibuka"},
|
||||
{"crx_nolebplcbgieabkblgiaacdpgehlopag", "apps.com.tianqitong"},
|
||||
{"crx_maghncnmccfbmkekccpmkjjfcmdnnlip", "apps.com.youjoy.strugglelandlord"},
|
||||
{"crx_heliimhfjgfabpgfecgdhackhelmocic", "apps.cn.emoney"},
|
||||
{"crx_jkgmneeafmgjillhgmjbaipnakfiidpm", "apps.com.instagram"},
|
||||
{"crx_cdbkhmfmikobpndfhiphdbkjklbmnakg", "apps.com.easymindmap"},
|
||||
{"crx_djflcciklfljleibeinjmjdnmenkciab", "apps.com.lgj.thunderbattle"},
|
||||
{"crx_ffdgbolnndgeflkapnmoefhjhkeilfff", "apps.com.qianlong"},
|
||||
{"crx_fmpniepgiofckbfgahajldgoelogdoap", "apps.com.windhd"},
|
||||
{"crx_dokjmallmkihbgefmladclcdcinjlnpj", "apps.com.youdao.hanyu"},
|
||||
{"crx_dicimeimfmbfcklbjdpnlmjgegcfilhm", "apps.com.ibookstar"},
|
||||
{"crx_cokkcjnpjfffianjbpjbcgjefningkjm", "apps.com.yidianzixun"},
|
||||
{"crx_ehflkacdpmeehailmcknlnkmjalehdah", "apps.com.xplane"},
|
||||
{"crx_iedokjbbjejfinokgifgecmboncmkbhb", "apps.com.wedevote"},
|
||||
{"crx_eaefcagiihjpndconigdpdmcbpcamaok", "apps.com.tongwei.blockbreaker"},
|
||||
{"crx_mkjjfibpccammnliaalefmlekiiikikj", "apps.com.dayima"},
|
||||
{"crx_gflkpppiigdigkemnjlonilmglokliol", "apps.com.cookpad"},
|
||||
{"crx_jfhpkchgedddadekfeganigbenbfaohe", "apps.com.issuu"},
|
||||
{"crx_ggkmfnbkldhmkehabgcbnmlccfbnoldo", "apps.bible.cbol"},
|
||||
{"crx_phlhkholfcljapmcidanddmhpcphlfng", "apps.com.kanjian.radio"},
|
||||
{"crx_bjgfcighhaahojkibojkdmpdihhcehfm", "apps.de.danoeh.antennapod"},
|
||||
{"crx_kldipknjommdfkifomkmcpbcnpmcnbfi", "apps.com.asoftmurmur"},
|
||||
{"crx_jfhlegimcipljdcionjbipealofoncmd", "apps.com.tencentnews"},
|
||||
{"crx_aikgmfkpmmclmpooohngmcdimgcocoaj", "apps.com.tonghuashun"},
|
||||
{"crx_ifimglalpdeoaffjmmihoofapmpflkad", "apps.com.letv.lecloud.disk"},
|
||||
{"crx_pllcekmbablpiogkinogefpdjkmgicbp", "apps.com.hwadzanebook"},
|
||||
{"crx_ohcknkkbjmgdfcejpbmhjbohnepcagkc", "apps.com.douban.radio"},
|
||||
};
|
||||
|
||||
WindowIdentify::WindowIdentify(Dock *_dock, QObject *parent)
|
||||
: QObject(parent)
|
||||
, dock(_dock)
|
||||
{
|
||||
identifyWindowFuns["Android"] = identifyWindowAndroid;
|
||||
identifyWindowFuns["PidEnv"] = identifyWindowByPidEnv;
|
||||
identifyWindowFuns["CmdlineTurboBooster"] = identifyWindowByCmdlineTurboBooster;
|
||||
identifyWindowFuns["Cmdline-XWalk"] = identifyWindowByCmdlineXWalk;
|
||||
identifyWindowFuns["FlatpakAppID"] = identifyWindowByFlatpakAppID;
|
||||
identifyWindowFuns["CrxId"] = identifyWindowByCrxId;
|
||||
identifyWindowFuns["Rule"] = identifyWindowByRule;
|
||||
identifyWindowFuns["Bamf"] = identifyWindowByBamf;
|
||||
identifyWindowFuns["Pid"] = identifyWindowByPid;
|
||||
identifyWindowFuns["Scratch"] = identifyWindowByScratch;
|
||||
identifyWindowFuns["GtkAppId"] = identifyWindowByGtkAppId;
|
||||
identifyWindowFuns["WmClass"] = identifyWindowByWmClass;
|
||||
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindow(WindowInfoBase *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
//qInfo() << "identifyWindow: window id " << winInfo->getXid() << " innerId " << winInfo->getInnerId();
|
||||
if (winInfo->getWindowType() == "X11")
|
||||
ret = identifyWindowX11(static_cast<WindowInfoX *>(winInfo), innerId);
|
||||
else if (winInfo->getWindowType() == "Wayland")
|
||||
ret = identifyWindowWayland(static_cast<WindowInfoK *>(winInfo), innerId);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowX11(WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *appInfo = nullptr;
|
||||
if (winInfo->getInnerId() == "") {
|
||||
qInfo() << "identify WindowX11: innerId is empty";
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
for (auto iter = identifyWindowFuns.begin(); iter != identifyWindowFuns.end(); iter++) {
|
||||
QString name = iter.key();
|
||||
IdentifyFunc func = iter.value();
|
||||
qInfo() << "identifyWindowX11: try " << name;
|
||||
appInfo = func(dock, winInfo, innerId);
|
||||
if (appInfo) { // TODO: if name == "Pid", appInfo may by nullptr
|
||||
// 识别成功
|
||||
qInfo() << "identify Window by " << name << " innerId " << appInfo->getInnerId() << " success!";
|
||||
AppInfo *fixedAppInfo = fixAutostartAppInfo(appInfo->getFileName());
|
||||
if (fixedAppInfo) {
|
||||
delete appInfo;
|
||||
appInfo = fixedAppInfo;
|
||||
appInfo->setIdentifyMethod(name + "+FixAutostart");
|
||||
innerId = appInfo->getInnerId();
|
||||
} else {
|
||||
appInfo->setIdentifyMethod(name);
|
||||
}
|
||||
return appInfo;
|
||||
}
|
||||
}
|
||||
|
||||
qInfo() << "identifyWindowX11: failed";
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowWayland(WindowInfoK *winInfo, QString &innerId)
|
||||
{
|
||||
// TODO: 对桌面调起的文管应用做规避处理,需要在此处添加,因为初始化时appId和title为空
|
||||
if (winInfo->getAppId() == "dde-desktop" && dock->shouldShowOnDock(winInfo)) {
|
||||
winInfo->setAppId("dde-file-manager");
|
||||
}
|
||||
|
||||
QString appId = winInfo->getAppId();
|
||||
if (appId.isEmpty()) {
|
||||
QString title = winInfo->getTitle();
|
||||
// TODO: 对于appId为空的情况,使用title过滤,此项修改针对浏览器下载窗口
|
||||
|
||||
}
|
||||
|
||||
// 先使用appId获取appInfo,如果不能成功获取再使用GIO_LAUNCHED_DESKTOP_FILE环境变量获取
|
||||
AppInfo *appInfo = new AppInfo(appId);
|
||||
if (!appInfo->isValidApp() && winInfo->getProcess()) {
|
||||
ProcessInfo *process = winInfo->getProcess();
|
||||
std::string desktopFilePath = process->getEnv("GIO_LAUNCHED_DESKTOP_FILE");
|
||||
if (DString::endWith(desktopFilePath, ".desktop")) {
|
||||
appInfo = new AppInfo(desktopFilePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// autoStart
|
||||
if (appInfo->isValidApp()) {
|
||||
AppInfo *fixedAppInfo = fixAutostartAppInfo(appInfo->getFileName());
|
||||
if (fixedAppInfo) {
|
||||
delete appInfo;
|
||||
appInfo = fixedAppInfo;
|
||||
appInfo->setIdentifyMethod("FixAutostart");
|
||||
}
|
||||
} else {
|
||||
// bamf
|
||||
XWindow winId = winInfo->getXid();
|
||||
QString desktop = dock->getDesktopFromWindowByBamf(winId);
|
||||
if (!desktop.isEmpty()) {
|
||||
appInfo = new AppInfo(desktop);
|
||||
}
|
||||
|
||||
WMClass wmClass = XCB->getWMClass(winId);
|
||||
if (wmClass.instanceName.size() > 0) {
|
||||
QString instance(wmClass.instanceName.c_str());
|
||||
appInfo = new AppInfo("org.deepin.flatdeb." + instance);
|
||||
if (appInfo)
|
||||
return appInfo;
|
||||
|
||||
appInfo = new AppInfo(instance);
|
||||
if (appInfo)
|
||||
return appInfo;
|
||||
|
||||
if (wmClass.className.size() > 0) {
|
||||
appInfo = new AppInfo(wmClass.className.c_str());
|
||||
if (appInfo)
|
||||
return appInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (appInfo)
|
||||
innerId = appInfo->getInnerId();
|
||||
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowAndroid(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
int32_t androidId = getAndroidUengineId(winInfo->getXid());
|
||||
QString androidName = getAndroidUengineName(winInfo->getXid());
|
||||
if (androidId != -1 && androidName != "") {
|
||||
QString desktopPath = "/usr/share/applications/uengine." + androidName + ".desktop";
|
||||
DesktopInfo desktopInfo(desktopPath.toStdString());
|
||||
if (!desktopInfo.isValidDesktop()) {
|
||||
qInfo() << "identifyWindowAndroid: not exist DesktopFile " << desktopPath;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = new AppInfo(desktopInfo);
|
||||
ret->setIdentifyMethod("Android");
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByPidEnv(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
int pid = winInfo->getPid();
|
||||
auto process = winInfo->getProcess();
|
||||
qInfo() << "identifyWindowByPidEnv: pid=" << pid << " WindowId=" << winInfo->getXid();
|
||||
if (pid != 0 && process) {
|
||||
QString launchedDesktopFile = process->getEnv("GIO_LAUNCHED_DESKTOP_FILE").c_str();
|
||||
QString launchedDesktopFilePidStr = process->getEnv("GIO_LAUNCHED_DESKTOP_FILE_PID").c_str();
|
||||
int launchedDesktopFilePid = launchedDesktopFilePidStr.toInt();
|
||||
qInfo() << "launchedDesktopFilePid=" << launchedDesktopFilePid << " launchedDesktopFile=" << launchedDesktopFile;
|
||||
|
||||
// 以下 2 种情况下,才能信任环境变量 GIO_LAUNCHED_DESKTOP_FILE。
|
||||
// 1. 当窗口 pid 和 launchedDesktopFilePid 相同时;
|
||||
// 2. 当窗口的进程的父进程 id(即 ppid)和 launchedDesktopFilePid 相同,
|
||||
// 并且该父进程是 sh 或 bash 时。
|
||||
bool needTry = false;
|
||||
if (pid == launchedDesktopFilePid) {
|
||||
needTry = true;
|
||||
} else if (process->getPpid() && process->getPpid() == launchedDesktopFilePid) {
|
||||
Process parentProcess(launchedDesktopFilePid);
|
||||
auto parentCmdLine = parentProcess.getCmdLine();
|
||||
if (parentCmdLine.size() > 0) {
|
||||
qInfo() << "ppid equal " << "parentCmdLine[0]:" << parentCmdLine[0].c_str();
|
||||
QString cmd0 = parentCmdLine[0].c_str();
|
||||
int pos = cmd0.lastIndexOf('/');
|
||||
if (pos > 0)
|
||||
cmd0 = cmd0.remove(0, pos + 1);
|
||||
|
||||
if (cmd0 == "sh" || cmd0 == "bash")
|
||||
needTry = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needTry) {
|
||||
ret = new AppInfo(launchedDesktopFile);
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByCmdlineTurboBooster(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
int pid = winInfo->getPid();
|
||||
ProcessInfo *process = winInfo->getProcess();
|
||||
if (pid != 0 && process) {
|
||||
auto cmdline = process->getCmdLine();
|
||||
if (cmdline.size() > 0) {
|
||||
QString desktopFile;
|
||||
if (DString::endWith(cmdline[0], ".desktop")) {
|
||||
desktopFile = cmdline[0].c_str();
|
||||
} else if (QString(cmdline[0].c_str()).contains("/applications/")) {
|
||||
QFileInfo fileInfo(cmdline[0].c_str());
|
||||
QString path = fileInfo.path();
|
||||
QString base = fileInfo.baseName();
|
||||
QDir dir(path);
|
||||
QStringList files = dir.entryList(QDir::Files);
|
||||
for (auto f : files) {
|
||||
if (f.contains(path + "/" + base + ".desktop")) {
|
||||
desktopFile = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qInfo() << "identifyWindowByCmdlineTurboBooster: desktopFile is " << desktopFile;
|
||||
if (!desktopFile.isEmpty()) {
|
||||
ret = new AppInfo(desktopFile);
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByCmdlineXWalk(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
qInfo() << "identifyWindowByCmdlineXWalk: windowId=" << winInfo->getXid();
|
||||
AppInfo *ret = nullptr;
|
||||
do {
|
||||
auto process = winInfo->getProcess();
|
||||
if (!process || !winInfo->getPid())
|
||||
break;
|
||||
|
||||
QString exe = process->getExe().c_str();
|
||||
QFileInfo file(exe);
|
||||
QString exeBase = file.baseName();
|
||||
auto args = process->getArgs();
|
||||
if (exe != "xwalk" || args.size() == 0)
|
||||
break;
|
||||
|
||||
QString lastArg = args[args.size() - 1].c_str();
|
||||
file.setFile(lastArg);
|
||||
if (file.baseName() == "manifest.json") {
|
||||
auto strs = lastArg.split("/");
|
||||
if (strs.size() > 3 && strs[strs.size() - 2].size() > 0) { // appId为 strs倒数第二个字符串
|
||||
ret = new AppInfo(strs[strs.size() - 2]);
|
||||
innerId = ret->getInnerId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qInfo() << "identifyWindowByCmdlineXWalk: failed";
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByFlatpakAppID(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
QString flatpak = winInfo->getFlatpakAppId();
|
||||
qInfo() << "identifyWindowByFlatpakAppID: flatpak:" << flatpak;
|
||||
if (flatpak.startsWith("app/")) {
|
||||
auto parts = flatpak.split("/");
|
||||
if (parts.size() > 0) {
|
||||
QString appId = parts[1];
|
||||
ret = new AppInfo(appId);
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByCrxId(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
WMClass wmClass = XCB->getWMClass(winInfo->getXid());
|
||||
QString className, instanceName;
|
||||
className.append(wmClass.className.c_str());
|
||||
instanceName.append(wmClass.instanceName.c_str());
|
||||
|
||||
if (className.toLower() == "chromium-browser" && instanceName.toLower().startsWith("crx_")) {
|
||||
if (crxAppIdMap.find(instanceName.toLower()) != crxAppIdMap.end()) {
|
||||
QString appId = crxAppIdMap[instanceName.toLower()];
|
||||
qInfo() << "identifyWindowByCrxId: appId " << appId;
|
||||
ret = new AppInfo(appId);
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByRule(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
qInfo() << "identifyWindowByRule: windowId=" << winInfo->getXid();
|
||||
AppInfo *ret = nullptr;
|
||||
QString matchStr = patterns.match(winInfo);
|
||||
if (matchStr.isEmpty())
|
||||
return ret;
|
||||
|
||||
if (matchStr.size() > 4 && matchStr.startsWith("id=")) {
|
||||
matchStr.remove(0, 3);
|
||||
ret = new AppInfo(matchStr);
|
||||
} else if (matchStr == "env") {
|
||||
auto process = winInfo->getProcess();
|
||||
if (process) {
|
||||
QString launchedDesktopFile = process->getEnv("GIO_LAUNCHED_DESKTOP_FILE").c_str();
|
||||
if (!launchedDesktopFile.isEmpty())
|
||||
ret = new AppInfo(launchedDesktopFile);
|
||||
}
|
||||
} else {
|
||||
qInfo() << "patterns match bad result";
|
||||
}
|
||||
|
||||
if (ret)
|
||||
innerId = ret->getInnerId();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByBamf(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
XWindow xid = winInfo->getXid();
|
||||
qInfo() << "identifyWindowByBamf: windowId=" << xid;
|
||||
QString desktopFile;
|
||||
// 重试 bamf 识别,yozo office 的窗口经常要第二次时才能识别到。
|
||||
for (int i=0; i<3; i++) {
|
||||
desktopFile = _dock->getDesktopFromWindowByBamf(xid);
|
||||
if (!desktopFile.isEmpty())
|
||||
break;
|
||||
|
||||
QThread::msleep(100);
|
||||
}
|
||||
|
||||
if (!desktopFile.isEmpty()) {
|
||||
ret = new AppInfo(desktopFile);
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByPid(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
if (winInfo->getPid() > 10) {
|
||||
auto entry = _dock->getEntryByWindowId(winInfo->getPid());
|
||||
if (entry) {
|
||||
ret = entry->getApp();
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByScratch(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
QString desktopFile = scratchDir + winInfo->getInnerId() + ".desktop";
|
||||
qInfo() << "identifyWindowByScratch: xid " << winInfo->getXid() << " desktopFile" << desktopFile;
|
||||
QFile file(desktopFile);
|
||||
|
||||
if (file.exists()) {
|
||||
ret = new AppInfo(desktopFile);
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByGtkAppId(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
QString gtkAppId = winInfo->getGtkAppId();
|
||||
if (!gtkAppId.isEmpty()) {
|
||||
ret = new AppInfo(gtkAppId);
|
||||
innerId = ret->getInnerId();
|
||||
}
|
||||
|
||||
qInfo() << "identifyWindowByGtkAppId: gtkAppId:" << gtkAppId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::identifyWindowByWmClass(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
|
||||
{
|
||||
AppInfo *ret = nullptr;
|
||||
WMClass wmClass = winInfo->getWMClass();
|
||||
do {
|
||||
if (wmClass.instanceName.size() > 0) {
|
||||
// example:
|
||||
// WM_CLASS(STRING) = "Brackets", "Brackets"
|
||||
// wm class instance is Brackets
|
||||
// try app id org.deepin.flatdeb.brackets
|
||||
ret = new AppInfo("org.deepin.flatdeb." + QString(wmClass.instanceName.c_str()).toLower());
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = new AppInfo(wmClass.instanceName.c_str());
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (wmClass.className.size() > 0) {
|
||||
ret = new AppInfo(wmClass.className.c_str());
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (ret)
|
||||
innerId = ret->getInnerId();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppInfo *WindowIdentify::fixAutostartAppInfo(QString fileName)
|
||||
{
|
||||
QFileInfo file(fileName);
|
||||
QString filePath = file.absolutePath();
|
||||
bool isAutoStart = false;
|
||||
for (auto &dir : BaseDir::autoStartDirs()) {
|
||||
if (QString(dir.c_str()).contains(filePath)) {
|
||||
isAutoStart = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isAutoStart ? new AppInfo(file.baseName()) : nullptr;
|
||||
}
|
||||
|
||||
int32_t WindowIdentify::getAndroidUengineId(XWindow winId)
|
||||
{
|
||||
// TODO 获取AndroidUengineId
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString WindowIdentify::getAndroidUengineName(XWindow winId)
|
||||
{
|
||||
// TODO 获取AndroidUengineName
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
75
src/modules/dock/windowidentify.h
Normal file
75
src/modules/dock/windowidentify.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WINDOWIDENTIFY_H
|
||||
#define WINDOWIDENTIFY_H
|
||||
|
||||
#include "windowpatterns.h"
|
||||
#include "windowinfok.h"
|
||||
#include "windowinfox.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QMap>
|
||||
|
||||
class AppInfo;
|
||||
class Dock;
|
||||
|
||||
typedef AppInfo *(*IdentifyFunc)(Dock *, WindowInfoX*, QString &innerId);
|
||||
|
||||
// 应用窗口识别类
|
||||
class WindowIdentify : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WindowIdentify(Dock *_dock, QObject *parent = nullptr);
|
||||
|
||||
AppInfo *identifyWindow(WindowInfoBase *winInfo, QString &innerId);
|
||||
AppInfo *identifyWindowX11(WindowInfoX *winInfo, QString &innerId);
|
||||
AppInfo *identifyWindowWayland(WindowInfoK *winInfo, QString &innerId);
|
||||
|
||||
static AppInfo *identifyWindowAndroid(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByPidEnv(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByCmdlineTurboBooster(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByCmdlineXWalk(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByFlatpakAppID(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByCrxId(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByRule(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByBamf(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByPid(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByScratch(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByGtkAppId(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
static AppInfo *identifyWindowByWmClass(Dock *_dock, WindowInfoX *winInfo, QString &innerId);
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
private:
|
||||
AppInfo *fixAutostartAppInfo(QString fileName);
|
||||
static int32_t getAndroidUengineId(XWindow winId);
|
||||
static QString getAndroidUengineName(XWindow winId);
|
||||
|
||||
static WindowPatterns patterns; // 根据rule识别
|
||||
Dock *dock;
|
||||
QMap<QString, IdentifyFunc> identifyWindowFuns;
|
||||
};
|
||||
|
||||
#endif // IDENTIFYWINDOW_H
|
80
src/modules/dock/windowinfobase.h
Normal file
80
src/modules/dock/windowinfobase.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WINDOWINFOBASE_H
|
||||
#define WINDOWINFOBASE_H
|
||||
|
||||
#include "xcbutils.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
class Entry;
|
||||
class AppInfo;
|
||||
class ProcessInfo;
|
||||
class WindowInfoBase
|
||||
{
|
||||
public:
|
||||
WindowInfoBase() : entry(nullptr), app(nullptr), processInfo(nullptr) {}
|
||||
virtual ~WindowInfoBase() {}
|
||||
|
||||
|
||||
virtual bool shouldSkip() = 0;
|
||||
virtual QString getIcon() = 0;
|
||||
virtual QString getTitle() = 0;
|
||||
virtual bool isDemandingAttention() = 0;
|
||||
virtual void close(uint32_t timestamp) = 0;
|
||||
virtual void activate() = 0;
|
||||
virtual void minimize() = 0;
|
||||
virtual bool isMinimized() = 0;
|
||||
virtual int64_t getCreatedTime() = 0;
|
||||
virtual QString getWindowType() = 0;
|
||||
virtual QString getDisplayName() = 0;
|
||||
virtual bool allowClose() = 0;
|
||||
virtual void update() = 0;
|
||||
virtual void killClient() = 0;
|
||||
|
||||
XWindow getXid() {return xid;}
|
||||
void setEntry(Entry *value) {entry = value;}
|
||||
Entry *getEntry() {return entry;}
|
||||
QString getEntryInnerId() {return entryInnerId;}
|
||||
QString getInnerId() {return innerId;}
|
||||
void setEntryInnerId(QString value) {entryInnerId = value;}
|
||||
AppInfo *getAppInfo() {return app;}
|
||||
void setAppInfo(AppInfo *value) {app = value;}
|
||||
int getPid() {return pid;}
|
||||
ProcessInfo *getProcess() {return processInfo;}
|
||||
bool containAtom(QVector<XCBAtom> supports, XCBAtom ty) {return supports.indexOf(ty) != -1;}
|
||||
|
||||
protected:
|
||||
XWindow xid;
|
||||
QString title;
|
||||
QString icon;
|
||||
int pid;
|
||||
QString entryInnerId;
|
||||
QString innerId;
|
||||
Entry *entry;
|
||||
AppInfo *app;
|
||||
ProcessInfo *processInfo;
|
||||
int64_t createdTime;
|
||||
};
|
||||
|
||||
#endif // WINDOWINFOBASE_H
|
210
src/modules/dock/windowinfok.cpp
Normal file
210
src/modules/dock/windowinfok.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "windowinfok.h"
|
||||
#include "entry.h"
|
||||
#include "processinfo.h"
|
||||
#include "appinfo.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
WindowInfoK::WindowInfoK(PlasmaWindow *window, XWindow _xid)
|
||||
: WindowInfoBase ()
|
||||
, updateCalled(false)
|
||||
, internalId(0)
|
||||
, demaningAttention(false)
|
||||
, closeable(true)
|
||||
, minimized(true)
|
||||
, plasmaWindow(window)
|
||||
{
|
||||
xid = _xid;
|
||||
createdTime = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); // 获取当前时间,精确到纳秒
|
||||
}
|
||||
|
||||
WindowInfoK::~WindowInfoK()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool WindowInfoK::shouldSkip()
|
||||
{
|
||||
if (!updateCalled) {
|
||||
update();
|
||||
updateCalled = true;
|
||||
}
|
||||
|
||||
bool skip = plasmaWindow->SkipTaskbar();
|
||||
|
||||
// 添加窗口能否最小化判断, 如果窗口不能最小化则隐藏任务栏图标
|
||||
bool canMinimize = false;
|
||||
canMinimize = plasmaWindow->IsMinimizeable();
|
||||
if (!canMinimize)
|
||||
skip = true;
|
||||
|
||||
if (skip) {
|
||||
// 白名单, 过滤类似“欢迎应用”, 没有最小化窗口但是需要在任务栏显示图标
|
||||
QStringList list { "dde-introduction"};
|
||||
if (list.indexOf(appId) != -1)
|
||||
skip = false;
|
||||
}
|
||||
|
||||
return skip;
|
||||
}
|
||||
|
||||
QString WindowInfoK::getIcon()
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
|
||||
QString WindowInfoK::getTitle()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
bool WindowInfoK::isDemandingAttention()
|
||||
{
|
||||
return demaningAttention;
|
||||
}
|
||||
|
||||
bool WindowInfoK::allowClose()
|
||||
{
|
||||
return closeable;
|
||||
}
|
||||
|
||||
void WindowInfoK::close(uint32_t timestamp)
|
||||
{
|
||||
plasmaWindow->RequestClose();
|
||||
}
|
||||
|
||||
QString WindowInfoK::getAppId()
|
||||
{
|
||||
return appId;
|
||||
}
|
||||
|
||||
void WindowInfoK::setAppId(QString _appId)
|
||||
{
|
||||
appId = _appId;
|
||||
}
|
||||
|
||||
void WindowInfoK::activate()
|
||||
{
|
||||
plasmaWindow->RequestActivate();
|
||||
}
|
||||
|
||||
void WindowInfoK::minimize()
|
||||
{
|
||||
plasmaWindow->RequestToggleMinimized();
|
||||
}
|
||||
|
||||
bool WindowInfoK::isMinimized()
|
||||
{
|
||||
return minimized;
|
||||
}
|
||||
|
||||
bool WindowInfoK::changeXid(XWindow _xid)
|
||||
{
|
||||
xid = _xid;
|
||||
return true;
|
||||
}
|
||||
|
||||
PlasmaWindow *WindowInfoK::getPlasmaWindow()
|
||||
{
|
||||
return plasmaWindow;
|
||||
}
|
||||
|
||||
bool WindowInfoK::updateGeometry()
|
||||
{
|
||||
Rect rect = plasmaWindow->Geometry();
|
||||
if (geometry == rect)
|
||||
return false;
|
||||
|
||||
geometry = rect;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WindowInfoK::updateTitle()
|
||||
{
|
||||
title = plasmaWindow->Title();
|
||||
}
|
||||
|
||||
void WindowInfoK::updateDemandingAttention()
|
||||
{
|
||||
demaningAttention = plasmaWindow->IsDemandingAttention();
|
||||
}
|
||||
|
||||
void WindowInfoK::updateIcon()
|
||||
{
|
||||
icon = plasmaWindow->Icon();
|
||||
}
|
||||
|
||||
void WindowInfoK::updateAppId()
|
||||
{
|
||||
appId = plasmaWindow->AppId();
|
||||
}
|
||||
|
||||
void WindowInfoK::updateInternalId()
|
||||
{
|
||||
internalId = plasmaWindow->InternalId();
|
||||
}
|
||||
|
||||
void WindowInfoK::updateCloseable()
|
||||
{
|
||||
closeable = plasmaWindow->IsCloseable();
|
||||
}
|
||||
|
||||
void WindowInfoK::updateProcessInfo()
|
||||
{
|
||||
pid = plasmaWindow->Pid();
|
||||
processInfo = new ProcessInfo(pid);
|
||||
}
|
||||
|
||||
int64_t WindowInfoK::getCreatedTime()
|
||||
{
|
||||
return createdTime;
|
||||
}
|
||||
|
||||
// 主要是为兼容X11
|
||||
QString WindowInfoK::getDisplayName()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
QString WindowInfoK::getWindowType()
|
||||
{
|
||||
return "Wayland";
|
||||
}
|
||||
|
||||
void WindowInfoK::update()
|
||||
{
|
||||
updateInternalId();
|
||||
updateAppId();
|
||||
updateIcon();
|
||||
updateTitle();
|
||||
updateGeometry();
|
||||
updateDemandingAttention();
|
||||
updateCloseable();
|
||||
updateProcessInfo();
|
||||
}
|
||||
|
||||
void WindowInfoK::killClient()
|
||||
{
|
||||
}
|
||||
|
79
src/modules/dock/windowinfok.h
Normal file
79
src/modules/dock/windowinfok.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WINDOWINFOK_H
|
||||
#define WINDOWINFOK_H
|
||||
|
||||
#include "windowinfobase.h"
|
||||
#include "dbusplasmawindow.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class Entry;
|
||||
class ProcessInfo;
|
||||
|
||||
// wayland下窗口信息
|
||||
class WindowInfoK: public WindowInfoBase
|
||||
{
|
||||
public:
|
||||
WindowInfoK(PlasmaWindow *window, XWindow _xid = 0);
|
||||
virtual ~WindowInfoK();
|
||||
|
||||
virtual bool shouldSkip();
|
||||
virtual QString getIcon();
|
||||
virtual QString getTitle();
|
||||
virtual bool isDemandingAttention();
|
||||
virtual bool allowClose();
|
||||
virtual void close(uint32_t timestamp);
|
||||
virtual void activate();
|
||||
virtual void minimize();
|
||||
virtual bool isMinimized();
|
||||
virtual int64_t getCreatedTime();
|
||||
virtual QString getDisplayName();
|
||||
virtual QString getWindowType();
|
||||
virtual void update();
|
||||
virtual void killClient();
|
||||
|
||||
QString getAppId();
|
||||
void setAppId(QString _appId);
|
||||
bool changeXid(XWindow _xid);
|
||||
PlasmaWindow *getPlasmaWindow();
|
||||
bool updateGeometry();
|
||||
void updateTitle();
|
||||
void updateDemandingAttention();
|
||||
void updateIcon();
|
||||
void updateAppId();
|
||||
void updateInternalId();
|
||||
void updateCloseable();
|
||||
void updateProcessInfo();
|
||||
|
||||
private:
|
||||
bool updateCalled;
|
||||
QString appId;
|
||||
uint32_t internalId;
|
||||
bool demaningAttention;
|
||||
bool closeable;
|
||||
bool minimized;
|
||||
PlasmaWindow *plasmaWindow;
|
||||
Rect geometry;
|
||||
};
|
||||
|
||||
#endif // WINDOWINFOK_H
|
447
src/modules/dock/windowinfox.cpp
Normal file
447
src/modules/dock/windowinfox.cpp
Normal file
@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "windowinfox.h"
|
||||
#include "appinfo.h"
|
||||
#include "xcbutils.h"
|
||||
#include "dstring.h"
|
||||
#include "common.h"
|
||||
#include "processinfo.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
#define XCB XCBUtils::instance()
|
||||
|
||||
WindowInfoX::WindowInfoX(XWindow _xid)
|
||||
: WindowInfoBase ()
|
||||
, x(0)
|
||||
, y(0)
|
||||
, width(0)
|
||||
, height(0)
|
||||
, hasWMTransientFor(false)
|
||||
, hasXEmbedInfo(false)
|
||||
, updateCalled(false)
|
||||
{
|
||||
xid = _xid;
|
||||
createdTime = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); // 获取当前时间,精确到纳秒
|
||||
}
|
||||
|
||||
WindowInfoX::~WindowInfoX()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool WindowInfoX::shouldSkip()
|
||||
{
|
||||
qInfo() << "window " << xid << " shouldSkip?";
|
||||
if (!updateCalled) {
|
||||
update();
|
||||
updateCalled = true;
|
||||
}
|
||||
|
||||
if (hasWmStateSkipTaskBar() || isValidModal() || shouldSkipWithWMClass())
|
||||
return true;
|
||||
|
||||
for (auto atom : wmWindowType) {
|
||||
if (atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DIALOG") && !isActionMinimizeAllowed())
|
||||
return true;
|
||||
|
||||
if (atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_UTILITY")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_COMBO")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DESKTOP")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DND")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DOCK")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_DROPDOWN_MENU")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_MENU")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_POPUP_MENU")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_SPLASH")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_TOOLBAR")
|
||||
|| atom == XCB->getAtom("_NET_WM_WINDOW_TYPE_TOOLTIP"))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString WindowInfoX::getIcon()
|
||||
{
|
||||
if (icon.isEmpty())
|
||||
icon = getIconFromWindow();
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
void WindowInfoX::activate()
|
||||
{
|
||||
XCB->setActiveWindow(xid);
|
||||
}
|
||||
|
||||
void WindowInfoX::minimize()
|
||||
{
|
||||
XCB->minimizeWindow(xid);
|
||||
}
|
||||
|
||||
bool WindowInfoX::isMinimized()
|
||||
{
|
||||
return containAtom(wmState, XCB->getAtom("_NET_WM_STATE_HIDDEN"));
|
||||
}
|
||||
|
||||
int64_t WindowInfoX::getCreatedTime()
|
||||
{
|
||||
return createdTime;
|
||||
}
|
||||
|
||||
QString WindowInfoX::getWindowType()
|
||||
{
|
||||
return "X11";
|
||||
}
|
||||
|
||||
bool WindowInfoX::allowClose()
|
||||
{
|
||||
// 允许关闭的条件:
|
||||
// 1. 不设置 functions 字段,即MotifHintFunctions 标志位;
|
||||
// 2. 或者设置了 functions 字段并且 设置了 MotifFunctionAll 标志位;
|
||||
// 3. 或者设置了 functions 字段并且 设置了 MotifFunctionClose 标志位。
|
||||
// 相关定义在 motif-2.3.8/lib/Xm/MwmUtil.h 。
|
||||
if ((motifWmHints.flags & MotifHintFunctions) == 0
|
||||
|| (motifWmHints.functions & MotifFunctionAll) != 0
|
||||
|| (motifWmHints.functions & MotifFunctionClose) != 0)
|
||||
return true;
|
||||
|
||||
for (auto action : wmAllowedActions) {
|
||||
if (action == XCB->getAtom("_NET_WM_ACTION_CLOSE")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString WindowInfoX::getDisplayName()
|
||||
{
|
||||
XWindow winId = xid;
|
||||
//QString role = wmRole;
|
||||
QString className(wmClass.className.c_str());
|
||||
QString instance;
|
||||
if (wmClass.instanceName.size() > 0) {
|
||||
int pos = QString(wmClass.instanceName.c_str()).lastIndexOf('/');
|
||||
if (pos != -1)
|
||||
instance.remove(0, pos + 1);
|
||||
}
|
||||
qInfo() << "getDisplayName class:" << className << " ,instance:" << instance;
|
||||
|
||||
//if (!role.isEmpty() && !className.isEmpty())
|
||||
// return className + " " + role;
|
||||
|
||||
if (!className.isEmpty())
|
||||
return className;
|
||||
|
||||
if (!instance.isEmpty())
|
||||
return instance;
|
||||
|
||||
|
||||
QString _wmName = wmName;
|
||||
if (!_wmName.isEmpty()) {
|
||||
int pos = _wmName.lastIndexOf('-');
|
||||
if (pos != -1 && !_wmName.startsWith("-")) {
|
||||
_wmName.truncate(pos);
|
||||
return _wmName;
|
||||
}
|
||||
}
|
||||
|
||||
if (processInfo) {
|
||||
QString exe {processInfo->getEnv("exe").c_str()};
|
||||
if (!exe.isEmpty())
|
||||
return exe;
|
||||
}
|
||||
|
||||
return QString("window:%1").arg(winId);
|
||||
}
|
||||
|
||||
void WindowInfoX::killClient()
|
||||
{
|
||||
XCB->killClientChecked(xid);
|
||||
}
|
||||
|
||||
QString WindowInfoX::getGtkAppId()
|
||||
{
|
||||
return gtkAppId;
|
||||
}
|
||||
|
||||
QString WindowInfoX::getFlatpakAppId()
|
||||
{
|
||||
return flatpakAppId;
|
||||
}
|
||||
|
||||
QString WindowInfoX::getWmRole()
|
||||
{
|
||||
return wmRole;
|
||||
}
|
||||
|
||||
WMClass WindowInfoX::getWMClass()
|
||||
{
|
||||
return wmClass;
|
||||
}
|
||||
|
||||
QString WindowInfoX::getWMName()
|
||||
{
|
||||
return wmName;
|
||||
}
|
||||
|
||||
ConfigureEvent *WindowInfoX::getLastConfigureEvent()
|
||||
{
|
||||
return lastConfigureNotifyEvent;
|
||||
}
|
||||
|
||||
void WindowInfoX::setLastConfigureEvent(ConfigureEvent *event)
|
||||
{
|
||||
lastConfigureNotifyEvent = event;
|
||||
}
|
||||
|
||||
bool WindowInfoX::isGeometryChanged(int _x, int _y, int _width, int _height)
|
||||
{
|
||||
return !(_x == x && _y == y && _width == width && _height == height);
|
||||
}
|
||||
|
||||
void WindowInfoX::setGtkAppId(QString _gtkAppId)
|
||||
{
|
||||
gtkAppId = _gtkAppId;
|
||||
}
|
||||
|
||||
void WindowInfoX::updateMotifWmHints()
|
||||
{
|
||||
// get from XCB
|
||||
motifWmHints = XCB->getWindowMotifWMHints(xid);
|
||||
}
|
||||
|
||||
// XEmbed info
|
||||
// 一般 tray icon 会带有 _XEMBED_INFO 属性
|
||||
void WindowInfoX::updateHasXEmbedInfo()
|
||||
{
|
||||
hasXEmbedInfo = XCB->hasXEmbedInfo(xid);
|
||||
}
|
||||
|
||||
QString WindowInfoX::genInnerId(WindowInfoX *winInfo)
|
||||
{
|
||||
XWindow winId = winInfo->getXid();
|
||||
QString wmClassName, wmInstance;
|
||||
WMClass wmClass = winInfo->getWMClass();
|
||||
if (wmClass.className.size() > 0)
|
||||
wmClassName = wmClass.className.c_str();
|
||||
|
||||
if (wmClass.instanceName.size() > 0) {
|
||||
QString instanceName(wmClass.instanceName.c_str());
|
||||
instanceName.remove(0, instanceName.lastIndexOf('/') + 1);
|
||||
wmInstance = instanceName;
|
||||
}
|
||||
|
||||
QString exe, args;
|
||||
if (winInfo->getProcess()) {
|
||||
exe = winInfo->getProcess()->getExe().c_str();
|
||||
for (auto arg : winInfo->getProcess()->getArgs()) {
|
||||
QString argStr(arg.c_str());
|
||||
if (argStr.contains("/") || argStr == "." || argStr == "..") {
|
||||
args += "%F ";
|
||||
} else {
|
||||
args += argStr + " ";
|
||||
}
|
||||
}
|
||||
|
||||
if (args.size() > 0)
|
||||
args.remove(args.size() - 2, 1);
|
||||
}
|
||||
|
||||
bool hasPid = winInfo->getPid() != 0;
|
||||
QString str;
|
||||
// NOTE: 不要使用 wmRole,有些程序总会改变这个值比如 GVim
|
||||
if (wmInstance.isEmpty() && wmClassName.isEmpty() && exe.isEmpty() && winInfo->getGtkAppId().isEmpty()) {
|
||||
if (!winInfo->getWMName().isEmpty())
|
||||
str = QString("wmName:%1").arg(winInfo->getWMName());
|
||||
else
|
||||
str = QString("windowId:%1").arg(winInfo->getXid());
|
||||
} else {
|
||||
str = QString("wmInstance:%1,wmClass:%2,exe:%3,args:%4,hasPid:%5,gtkAppId:%6").arg(wmInstance).arg(wmClassName).arg(exe).arg(args).arg(hasPid).arg(winInfo->getGtkAppId());
|
||||
}
|
||||
|
||||
QByteArray encryText = QCryptographicHash::hash(str.toLatin1(), QCryptographicHash::Md5);
|
||||
QString innerId = windowHashPrefix + encryText.toHex();
|
||||
qInfo() << "genInnerId window " << winId << " innerId :" << innerId;
|
||||
return innerId;
|
||||
}
|
||||
|
||||
// 更新窗口类型
|
||||
void WindowInfoX::updateWmWindowType()
|
||||
{
|
||||
wmWindowType.clear();
|
||||
for (auto ty : XCB->getWMWindoType(xid)) {
|
||||
wmWindowType.push_back(ty);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新窗口许可动作
|
||||
void WindowInfoX::updateWmAllowedActions()
|
||||
{
|
||||
wmAllowedActions.clear();
|
||||
for (auto action : XCB->getWMAllowedActions(xid)) {
|
||||
wmAllowedActions.push_back(action);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowInfoX::updateWmState()
|
||||
{
|
||||
wmState.clear();
|
||||
for (auto a : XCB->getWMState(xid)) {
|
||||
wmState.push_back(a);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowInfoX::updateWmClass()
|
||||
{
|
||||
wmClass = XCB->getWMClass(xid);
|
||||
}
|
||||
|
||||
void WindowInfoX::updateWmName()
|
||||
{
|
||||
auto name = XCB->getWMName(xid);
|
||||
if (!name.empty())
|
||||
wmName = name.c_str();
|
||||
|
||||
title = getTitle();
|
||||
}
|
||||
|
||||
void WindowInfoX::updateIcon()
|
||||
{
|
||||
icon = getIconFromWindow();
|
||||
}
|
||||
|
||||
void WindowInfoX::updateHasWmTransientFor()
|
||||
{
|
||||
if (XCB->getWMTransientFor(xid) == 1)
|
||||
hasWMTransientFor = true;
|
||||
}
|
||||
|
||||
void WindowInfoX::update()
|
||||
{
|
||||
updateWmClass();
|
||||
updateWmState();
|
||||
updateWmWindowType();
|
||||
updateWmAllowedActions();
|
||||
updateHasWmTransientFor();
|
||||
updateProcessInfo();
|
||||
updateWmName();
|
||||
innerId = genInnerId(this);
|
||||
}
|
||||
|
||||
// TODO 从窗口中获取图标, 并设置best size be used in Entry
|
||||
QString WindowInfoX::getIconFromWindow()
|
||||
{
|
||||
QString ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WindowInfoX::isActionMinimizeAllowed()
|
||||
{
|
||||
return containAtom(wmAllowedActions, XCB->getAtom("_NET_WM_ACTION_MINIMIZE"));
|
||||
}
|
||||
|
||||
bool WindowInfoX::hasWmStateDemandsAttention()
|
||||
{
|
||||
return containAtom(wmState, XCB->getAtom("_NET_WM_STATE_DEMANDS_ATTENTION"));
|
||||
}
|
||||
|
||||
bool WindowInfoX::hasWmStateSkipTaskBar()
|
||||
{
|
||||
return containAtom(wmState, XCB->getAtom("_NET_WM_STATE_SKIP_TASKBAR"));
|
||||
}
|
||||
|
||||
bool WindowInfoX::hasWmStateModal()
|
||||
{
|
||||
return containAtom(wmState, XCB->getAtom("_NET_WM_STATE_MODAL"));
|
||||
}
|
||||
|
||||
bool WindowInfoX::isValidModal()
|
||||
{
|
||||
return hasWmStateModal() && hasWmStateModal();
|
||||
}
|
||||
|
||||
// 通过WMClass判断是否需要隐藏此窗口
|
||||
bool WindowInfoX::shouldSkipWithWMClass()
|
||||
{
|
||||
bool ret = false;
|
||||
if (wmClass.instanceName == "explorer.exe" && wmClass.className == "Wine")
|
||||
ret = true;
|
||||
else if (wmClass.className == "dde-launcher")
|
||||
ret = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WindowInfoX::updateProcessInfo()
|
||||
{
|
||||
XWindow winId = xid;
|
||||
pid = XCB->getWMPid(winId);
|
||||
if (processInfo)
|
||||
delete processInfo;
|
||||
|
||||
processInfo = new ProcessInfo(pid);
|
||||
if (!processInfo) {
|
||||
// try WM_COMMAND
|
||||
auto wmComand = XCB->getWMCommand(winId);
|
||||
if (wmComand.size() > 0)
|
||||
processInfo = new ProcessInfo(wmComand);
|
||||
}
|
||||
|
||||
qInfo() << "updateProcessInfo: pid is " << pid;
|
||||
}
|
||||
|
||||
bool WindowInfoX::getUpdateCalled()
|
||||
{
|
||||
return updateCalled;
|
||||
}
|
||||
|
||||
void WindowInfoX::setInnerId(QString _innerId)
|
||||
{
|
||||
innerId = _innerId;
|
||||
}
|
||||
|
||||
QString WindowInfoX::getTitle()
|
||||
{
|
||||
QString name = wmName;
|
||||
if (name.isEmpty())
|
||||
name = getDisplayName();
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
bool WindowInfoX::isDemandingAttention()
|
||||
{
|
||||
return hasWmStateDemandsAttention();
|
||||
}
|
||||
|
||||
void WindowInfoX::close(uint32_t timestamp)
|
||||
{
|
||||
XCB->requestCloseWindow(xid, timestamp);
|
||||
}
|
||||
|
||||
|
108
src/modules/dock/windowinfox.h
Normal file
108
src/modules/dock/windowinfox.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WINDOWINFOX_H
|
||||
#define WINDOWINFOX_H
|
||||
|
||||
#include "windowinfobase.h"
|
||||
#include "xcbutils.h"
|
||||
|
||||
#include <QVector>
|
||||
|
||||
class AppInfo;
|
||||
|
||||
// X11下窗口信息 在明确X11环境下使用
|
||||
class WindowInfoX: public WindowInfoBase
|
||||
{
|
||||
public:
|
||||
WindowInfoX(XWindow _xid = 0);
|
||||
virtual ~WindowInfoX();
|
||||
|
||||
virtual bool shouldSkip();
|
||||
virtual QString getIcon();
|
||||
virtual QString getTitle();
|
||||
virtual bool isDemandingAttention();
|
||||
virtual void close(uint32_t timestamp);
|
||||
virtual void activate();
|
||||
virtual void minimize();
|
||||
virtual bool isMinimized();
|
||||
virtual int64_t getCreatedTime();
|
||||
virtual QString getDisplayName();
|
||||
virtual QString getWindowType();
|
||||
virtual bool allowClose();
|
||||
virtual void update();
|
||||
virtual void killClient();
|
||||
|
||||
QString genInnerId(WindowInfoX *winInfo);
|
||||
QString getGtkAppId();
|
||||
QString getFlatpakAppId();
|
||||
QString getWmRole();
|
||||
WMClass getWMClass();
|
||||
QString getWMName();
|
||||
void updateProcessInfo();
|
||||
bool getUpdateCalled();
|
||||
void setInnerId(QString _innerId);
|
||||
ConfigureEvent *getLastConfigureEvent();
|
||||
void setLastConfigureEvent(ConfigureEvent *event);
|
||||
bool isGeometryChanged(int _x, int _y, int _width, int _height);
|
||||
void setGtkAppId(QString _gtkAppId);
|
||||
|
||||
/************************更新XCB窗口属性*********************/
|
||||
void updateWmWindowType();
|
||||
void updateWmAllowedActions();
|
||||
void updateWmState();
|
||||
void updateWmClass();
|
||||
void updateMotifWmHints();
|
||||
void updateWmName();
|
||||
void updateIcon();
|
||||
void updateHasXEmbedInfo();
|
||||
void updateHasWmTransientFor();
|
||||
|
||||
private:
|
||||
QString getIconFromWindow();
|
||||
bool isActionMinimizeAllowed();
|
||||
bool hasWmStateDemandsAttention();
|
||||
bool hasWmStateSkipTaskBar();
|
||||
bool hasWmStateModal();
|
||||
bool isValidModal();
|
||||
bool shouldSkipWithWMClass();
|
||||
|
||||
int16_t x, y;
|
||||
uint16_t width, height;
|
||||
QVector<XCBAtom> wmState;
|
||||
QVector<XCBAtom> wmWindowType;
|
||||
QVector<XCBAtom> wmAllowedActions;
|
||||
bool hasWMTransientFor;
|
||||
WMClass wmClass;
|
||||
QString wmName;
|
||||
bool hasXEmbedInfo;
|
||||
|
||||
// 自定义atom属性
|
||||
QString gtkAppId;
|
||||
QString flatpakAppId;
|
||||
QString wmRole;
|
||||
MotifWMHints motifWmHints;
|
||||
|
||||
bool updateCalled;
|
||||
ConfigureEvent *lastConfigureNotifyEvent;
|
||||
};
|
||||
|
||||
#endif // WINDOWINFOX_H
|
229
src/modules/dock/windowpatterns.cpp
Normal file
229
src/modules/dock/windowpatterns.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "windowpatterns.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonArray>
|
||||
#include <QVariant>
|
||||
#include <QVariantMap>
|
||||
#include <QDebug>
|
||||
#include <dstring.h>
|
||||
#include <QRegExp>
|
||||
#include <QFile>
|
||||
|
||||
const int parsedFlagNegative = 0x001;
|
||||
const int parsedFlagIgnoreCase = 0x010;
|
||||
|
||||
bool contains(QString key, QString value) {
|
||||
return key.contains(value);
|
||||
}
|
||||
|
||||
bool containsIgnoreCase(QString key, QString value) {
|
||||
QString _key = key.toLower();
|
||||
QString _value = value.toLower();
|
||||
return _key.contains(_value);
|
||||
}
|
||||
|
||||
bool equal(QString key, QString value) {
|
||||
return key == value;
|
||||
}
|
||||
|
||||
bool equalIgnoreCase(QString key, QString value) {
|
||||
return key.toLower() == value.toLower();
|
||||
}
|
||||
|
||||
bool regexMatch(QString key, QString value) {
|
||||
QRegExp ruleRegex(value);
|
||||
return ruleRegex.exactMatch(key);
|
||||
}
|
||||
|
||||
bool regexMatchIgnoreCase(QString key, QString value) {
|
||||
QRegExp ruleRegex(value, Qt::CaseInsensitive);
|
||||
return ruleRegex.exactMatch(key);
|
||||
}
|
||||
|
||||
|
||||
RuleValueParse::RuleValueParse()
|
||||
: negative(0)
|
||||
, type(0)
|
||||
, flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool RuleValueParse::parse(QString parsedKey)
|
||||
{
|
||||
if (!fn)
|
||||
return false;
|
||||
|
||||
return negative ? fn(parsedKey, value) : !fn(parsedKey, value);
|
||||
}
|
||||
|
||||
bool RuleValueParse::match(const WindowInfoX *winInfo)
|
||||
{
|
||||
QString parsedKey;
|
||||
|
||||
return parse(parsedKey);
|
||||
}
|
||||
|
||||
|
||||
WindowPatterns::WindowPatterns()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString WindowPatterns::match(WindowInfoX *winInfo)
|
||||
{
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void WindowPatterns::loadWindowPatterns()
|
||||
{
|
||||
qInfo() << "---loadWindowPatterns";
|
||||
QFile file(windowPatternsFile);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
|
||||
file.close();
|
||||
if (!doc.isArray())
|
||||
return;
|
||||
|
||||
QJsonArray arr = doc.array();
|
||||
if (arr.size() == 0)
|
||||
return;
|
||||
|
||||
patterns.clear();
|
||||
for (auto iterp = arr.begin(); iterp != arr.end(); iterp++) {
|
||||
// 过滤非Object
|
||||
if (!(*iterp).isObject())
|
||||
continue;
|
||||
|
||||
QJsonObject patternObj = (*iterp).toObject();
|
||||
QVariantMap patternMap = patternObj.toVariantMap();
|
||||
WindowPattern pattern;
|
||||
for (auto infoIter = patternMap.begin(); infoIter != patternMap.end(); infoIter++) {
|
||||
QString ret = infoIter.key();
|
||||
QVariant value = infoIter.value();
|
||||
|
||||
if (ret == "ret") {
|
||||
pattern.result = value.toString();
|
||||
} else if (ret == "rules") {
|
||||
for (auto &item : value.toList()) {
|
||||
if (!item.isValid())
|
||||
continue;
|
||||
|
||||
if (item.toList().size() != 2)
|
||||
continue;
|
||||
|
||||
pattern.rules.push_back({item.toList()[0].toString(), item.toList()[1].toString()});
|
||||
}
|
||||
}
|
||||
}
|
||||
qInfo() << pattern.result;
|
||||
for (const auto &item : pattern.rules) {
|
||||
qInfo() << item[0] << " " << item[1];
|
||||
}
|
||||
patterns.push_back(pattern);
|
||||
}
|
||||
|
||||
// 解析patterns
|
||||
for (auto &pattern : patterns) {
|
||||
for (int i=0; i < pattern.rules.size(); i++) {
|
||||
RuleValueParse ruleValue = parseRule(pattern.rules[i]);
|
||||
pattern.parseRules.push_back(ruleValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "=:XXX" equal XXX
|
||||
// "=!XXX" not equal XXX
|
||||
|
||||
// "c:XXX" contains XXX
|
||||
// "c!XXX" not contains XXX
|
||||
|
||||
// "r:XXX" match regexp XXX
|
||||
// "r!XXX" not match regexp XXX
|
||||
|
||||
// e c r ignore case
|
||||
// = E C R not ignore case
|
||||
// 解析窗口类型规则
|
||||
RuleValueParse WindowPatterns::parseRule(QVector<QString> rule)
|
||||
{
|
||||
RuleValueParse ret;
|
||||
ret.key = rule[0];
|
||||
ret.original = rule[1];
|
||||
if (rule[1].size() < 2)
|
||||
return ret;
|
||||
|
||||
int len = ret.original.size() + 1;
|
||||
char *orig = static_cast<char *>(calloc(1, size_t(len)));
|
||||
if (!orig)
|
||||
return ret;
|
||||
|
||||
strncpy(orig, ret.original.toStdString().c_str(), size_t(len));
|
||||
switch (orig[1]) {
|
||||
case ':':
|
||||
case '!':
|
||||
ret.flags |= parsedFlagNegative;
|
||||
ret.negative = true;
|
||||
break;
|
||||
default:
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.value = QString(&orig[2]);
|
||||
ret.type = uint8_t(orig[0]);
|
||||
switch (orig[0]) {
|
||||
case 'C':
|
||||
ret.fn = contains;
|
||||
break;
|
||||
case 'c':
|
||||
ret.flags |= parsedFlagIgnoreCase;
|
||||
ret.fn = containsIgnoreCase;
|
||||
break;
|
||||
case '=':
|
||||
case 'E':
|
||||
ret.fn = equal;
|
||||
break;
|
||||
case 'e':
|
||||
ret.flags |= parsedFlagIgnoreCase;
|
||||
ret.fn = equalIgnoreCase;
|
||||
break;
|
||||
case 'R':
|
||||
ret.fn = regexMatch;
|
||||
break;
|
||||
case 'r':
|
||||
ret.flags |= parsedFlagIgnoreCase;
|
||||
ret.fn = regexMatchIgnoreCase;
|
||||
break;
|
||||
default:
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
65
src/modules/dock/windowpatterns.h
Normal file
65
src/modules/dock/windowpatterns.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WINDOWPATTERNS_H
|
||||
#define WINDOWPATTERNS_H
|
||||
|
||||
#include "windowinfox.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
struct RuleValueParse {
|
||||
RuleValueParse();
|
||||
bool parse(QString parsedKey);
|
||||
bool match(const WindowInfoX *winInfo);
|
||||
QString key;
|
||||
bool negative;
|
||||
bool (*fn)(QString, QString);
|
||||
uint8_t type;
|
||||
uint flags;
|
||||
QString original;
|
||||
QString value;
|
||||
};
|
||||
|
||||
class WindowPatterns
|
||||
{
|
||||
// 窗口类型匹配
|
||||
struct WindowPattern {
|
||||
QVector<QVector<QString>> rules; // rules
|
||||
QString result; // ret
|
||||
QVector< RuleValueParse> parseRules;
|
||||
};
|
||||
|
||||
public:
|
||||
WindowPatterns();
|
||||
|
||||
QString match(WindowInfoX *winInfo);
|
||||
|
||||
private:
|
||||
void loadWindowPatterns();
|
||||
RuleValueParse parseRule(QVector<QString> rule);
|
||||
QVector<WindowPattern> patterns;
|
||||
|
||||
};
|
||||
|
||||
#endif // WINDOWPATTERNS_H
|
438
src/modules/dock/x11manager.cpp
Normal file
438
src/modules/dock/x11manager.cpp
Normal file
@ -0,0 +1,438 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "x11manager.h"
|
||||
#include "dock.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
/*
|
||||
* 使用Xlib监听X Events
|
||||
* 使用XCB接口与X进行交互
|
||||
* */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xproto.h>
|
||||
|
||||
#define XCB XCBUtils::instance()
|
||||
|
||||
X11Manager::X11Manager(Dock *_dock, QObject *parent)
|
||||
: QObject(parent)
|
||||
, dock(_dock)
|
||||
, mutex(QMutex(QMutex::NonRecursive))
|
||||
, listenXEvent(true)
|
||||
{
|
||||
rootWindow = XCB->getRootWindow();
|
||||
}
|
||||
|
||||
void X11Manager::listenXEventUseXlib()
|
||||
{
|
||||
|
||||
Display *dpy;
|
||||
int screen;
|
||||
char *displayname = nullptr;
|
||||
Window w;
|
||||
XSetWindowAttributes attr;
|
||||
XWindowAttributes wattr;
|
||||
|
||||
dpy = XOpenDisplay (displayname);
|
||||
if (!dpy) {
|
||||
exit (1);
|
||||
}
|
||||
|
||||
screen = DefaultScreen (dpy);
|
||||
w = RootWindow(dpy, screen);
|
||||
|
||||
const struct {
|
||||
const char *name;
|
||||
long mask;
|
||||
} events[] = {
|
||||
{ "keyboard", KeyPressMask | KeyReleaseMask | KeymapStateMask },
|
||||
{ "mouse", ButtonPressMask | ButtonReleaseMask | EnterWindowMask |
|
||||
LeaveWindowMask | PointerMotionMask | Button1MotionMask |
|
||||
Button2MotionMask | Button3MotionMask | Button4MotionMask |
|
||||
Button5MotionMask | ButtonMotionMask },
|
||||
{ "button", ButtonPressMask | ButtonReleaseMask },
|
||||
{ "expose", ExposureMask },
|
||||
{ "visibility", VisibilityChangeMask },
|
||||
{ "structure", StructureNotifyMask },
|
||||
{ "substructure", SubstructureNotifyMask | SubstructureRedirectMask },
|
||||
{ "focus", FocusChangeMask },
|
||||
{ "property", PropertyChangeMask },
|
||||
{ "colormap", ColormapChangeMask },
|
||||
{ "owner_grab_button", OwnerGrabButtonMask },
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
long mask = 0;
|
||||
for (int i = 0; events[i].name; i++)
|
||||
mask |= events[i].mask;
|
||||
|
||||
attr.event_mask = mask;
|
||||
|
||||
XGetWindowAttributes(dpy, w, &wattr);
|
||||
|
||||
attr.event_mask &= ~SubstructureRedirectMask;
|
||||
XSelectInput(dpy, w, attr.event_mask);
|
||||
|
||||
while (listenXEvent) {
|
||||
XEvent event;
|
||||
XNextEvent (dpy, &event);
|
||||
|
||||
if (event.type == DestroyNotify) {
|
||||
XDestroyWindowEvent *eD = (XDestroyWindowEvent *) (&event);
|
||||
//qInfo() << "DestroyNotify windowId=" << eD->window;
|
||||
|
||||
handleDestroyNotifyEvent(XWindow(eD->window));
|
||||
} else if (event.type == MapNotify) {
|
||||
XMapEvent *eM = (XMapEvent *)(&event);
|
||||
//qInfo() << "MapNotify windowId=" << eM->window;
|
||||
|
||||
handleMapNotifyEvent(XWindow(eM->window));
|
||||
} else if (event.type == ConfigureNotify ) {
|
||||
XConfigureEvent *eC = (XConfigureEvent *) (&event);
|
||||
//qInfo() << "ConfigureNotify windowId=" << eC->window;
|
||||
|
||||
handleConfigureNotifyEvent(XWindow(eC->window), eC->x, eC->y, eC->width, eC->height);
|
||||
} else if (event.type == PropertyNotify) {
|
||||
XPropertyEvent *eP = (XPropertyEvent *) (&event);
|
||||
//qInfo() << "PropertyNotify windowId=" << eP->window;
|
||||
|
||||
handlePropertyNotifyEvent(XWindow(eP->window), XCBAtom(eP->atom));
|
||||
} else {
|
||||
//qInfo() << "Unknown event type " << event.type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
XCloseDisplay (dpy);
|
||||
}
|
||||
|
||||
void X11Manager::listenXEventUseXCB()
|
||||
{
|
||||
/*
|
||||
xcb_get_window_attributes_cookie_t cookie = xcb_get_window_attributes(XCB->getConnect(), XCB->getRootWindow());
|
||||
xcb_get_window_attributes_reply_t *reply = xcb_get_window_attributes_reply(XCB->getConnect(), cookie, NULL);
|
||||
if (reply) {
|
||||
uint32_t valueMask = reply->your_event_mask;
|
||||
valueMask &= ~XCB_CW_OVERRIDE_REDIRECT;
|
||||
uint32_t mask[2] = {0};
|
||||
mask[0] = valueMask;
|
||||
//xcb_change_window_attributes(XCB->getConnect(), XCB->getRootWindow(), valueMask, mask);
|
||||
|
||||
free(reply);
|
||||
}
|
||||
|
||||
xcb_generic_event_t *event;
|
||||
while ( (event = xcb_wait_for_event (XCB->getConnect())) ) {
|
||||
eventHandler(event->response_type & ~0x80, event);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// 注册X11窗口
|
||||
WindowInfoX *X11Manager::registerWindow(XWindow xid)
|
||||
{
|
||||
qInfo() << "registWindow: windowId=" << xid;
|
||||
WindowInfoX *ret = nullptr;
|
||||
do {
|
||||
if (windowInfoMap.find(xid) != windowInfoMap.end()) {
|
||||
ret = windowInfoMap[xid];
|
||||
break;
|
||||
}
|
||||
|
||||
WindowInfoX *winInfo = new WindowInfoX(xid);
|
||||
if (!winInfo)
|
||||
break;
|
||||
|
||||
listenWindowXEvent(winInfo);
|
||||
windowInfoMap[xid] = winInfo;
|
||||
ret = winInfo;
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 取消注册X11窗口
|
||||
void X11Manager::unregisterWindow(XWindow xid)
|
||||
{
|
||||
qInfo() << "unregisterWindow: windowId=" << xid;
|
||||
if (windowInfoMap.find(xid) != windowInfoMap.end()) {
|
||||
windowInfoMap.remove(xid);
|
||||
}
|
||||
}
|
||||
|
||||
WindowInfoX *X11Manager::findWindowByXid(XWindow xid)
|
||||
{
|
||||
WindowInfoX *ret = nullptr;
|
||||
if (windowInfoMap.find(xid) != windowInfoMap.end())
|
||||
ret = windowInfoMap[xid];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void X11Manager::handleClientListChanged()
|
||||
{
|
||||
QSet<XWindow> newClientList, oldClientList, addClientList, rmClientList;
|
||||
for (auto atom : XCB->getClientList())
|
||||
newClientList.insert(atom);
|
||||
|
||||
for (auto atom : dock->getClientList())
|
||||
oldClientList.insert(atom);
|
||||
|
||||
addClientList = newClientList - oldClientList;
|
||||
rmClientList = oldClientList - newClientList;
|
||||
|
||||
for (auto xid : addClientList) {
|
||||
WindowInfoX *info = registerWindow(xid);
|
||||
if (!XCB->isGoodWindow(xid))
|
||||
continue;
|
||||
|
||||
uint32_t pid = XCB->getWMPid(xid);
|
||||
WMClass wmClass = XCB->getWMClass(xid);
|
||||
QString wmName(XCB->getWMName(xid).c_str());
|
||||
if (pid != 0 || (wmClass.className.size() > 0 && wmClass.instanceName.size() > 0)
|
||||
|| wmName.size() > 0 || XCB->getWMCommand(xid).size() > 0)
|
||||
dock->attachWindow(info);
|
||||
}
|
||||
|
||||
for (auto xid : rmClientList) {
|
||||
WindowInfoX *info = windowInfoMap[xid];
|
||||
if (info) {
|
||||
dock->detachWindow(info);
|
||||
unregisterWindow(xid);
|
||||
} else {
|
||||
// no window
|
||||
auto entry = dock->getEntryByWindowId(xid);
|
||||
if (entry && !dock->isDocked(entry->getFileName())) {
|
||||
dock->removeAppEntry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void X11Manager::handleActiveWindowChangedX()
|
||||
{
|
||||
XWindow active = XCB->getActiveWindow();
|
||||
WindowInfoX *info = findWindowByXid(active);
|
||||
dock->handleActiveWindowChanged(info);
|
||||
}
|
||||
|
||||
void X11Manager::listenRootWindowXEvent()
|
||||
{
|
||||
uint32_t eventMask = EventMask::XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
|
||||
XCB->registerEvents(rootWindow, eventMask);
|
||||
handleActiveWindowChangedX();
|
||||
handleClientListChanged();
|
||||
}
|
||||
|
||||
void X11Manager::listenWindowXEvent(WindowInfoX *winInfo)
|
||||
{
|
||||
uint32_t eventMask = EventMask::XCB_EVENT_MASK_PROPERTY_CHANGE | EventMask::XCB_EVENT_MASK_STRUCTURE_NOTIFY | EventMask::XCB_EVENT_MASK_VISIBILITY_CHANGE;
|
||||
XCB->registerEvents(winInfo->getXid(), eventMask);
|
||||
}
|
||||
|
||||
void X11Manager::handleRootWindowPropertyNotifyEvent(XCBAtom atom)
|
||||
{
|
||||
if (atom == XCB->getAtom("_NET_CLIENT_LIST"))
|
||||
handleClientListChanged();
|
||||
else if (atom == XCB->getAtom("_NET_ACTIVE_WINDOW"))
|
||||
handleActiveWindowChangedX();
|
||||
else if (atom == XCB->getAtom("_NET_SHOWING_DESKTOP"))
|
||||
Q_EMIT needUpdateHideState(false);
|
||||
}
|
||||
|
||||
// destory event
|
||||
void X11Manager::handleDestroyNotifyEvent(XWindow xid)
|
||||
{
|
||||
WindowInfoX *winInfo = findWindowByXid(xid);
|
||||
if (!winInfo)
|
||||
return;
|
||||
|
||||
dock->detachWindow(winInfo);
|
||||
unregisterWindow(xid);
|
||||
}
|
||||
|
||||
// map event
|
||||
void X11Manager::handleMapNotifyEvent(XWindow xid)
|
||||
{
|
||||
WindowInfoX *winInfo = registerWindow(xid);
|
||||
if (!winInfo)
|
||||
return;
|
||||
|
||||
QTimer::singleShot(2 * 1000, this, [&] {
|
||||
qInfo() << "handleMapNotifyEvent: pass 2s, now call idnetifyWindow, windowId=" << winInfo->getXid();
|
||||
QString innerId;
|
||||
AppInfo *appInfo = dock->identifyWindow(winInfo, innerId);
|
||||
dock->markAppLaunched(appInfo);
|
||||
});
|
||||
}
|
||||
|
||||
// config changed event 检测窗口大小调整和重绘应用
|
||||
void X11Manager::handleConfigureNotifyEvent(XWindow xid, int x, int y, int width, int height)
|
||||
{
|
||||
WindowInfoX *winInfo = findWindowByXid(xid);
|
||||
if (!winInfo || dock->getDockHideMode() != HideMode::SmartHide)
|
||||
return;
|
||||
|
||||
WMClass wmClass = winInfo->getWMClass();
|
||||
if (wmClass.className.c_str() == frontendWindowWmClass)
|
||||
return; // ignore frontend window ConfigureNotify event
|
||||
|
||||
Q_EMIT needUpdateHideState(winInfo->isGeometryChanged(x, y, width, height));
|
||||
}
|
||||
|
||||
// property changed event
|
||||
void X11Manager::handlePropertyNotifyEvent(XWindow xid, XCBAtom atom)
|
||||
{
|
||||
if (xid == rootWindow) {
|
||||
handleRootWindowPropertyNotifyEvent(atom);
|
||||
return;
|
||||
}
|
||||
|
||||
WindowInfoX *winInfo = findWindowByXid(xid);
|
||||
if (!winInfo)
|
||||
return;
|
||||
|
||||
QString newInnerId;
|
||||
bool needAttachOrDetach = false;
|
||||
if (atom == XCB->getAtom("_NET_WM_STATE")) {
|
||||
winInfo->updateWmState();
|
||||
needAttachOrDetach = true;
|
||||
} else if (atom == XCB->getAtom("_GTK_APPLICATION_ID")) {
|
||||
QString gtkAppId;
|
||||
winInfo->setGtkAppId(gtkAppId);
|
||||
newInnerId = winInfo->genInnerId(winInfo);
|
||||
} else if (atom == XCB->getAtom("_NET_WM_PID")) {
|
||||
winInfo->updateProcessInfo();
|
||||
newInnerId = winInfo->genInnerId(winInfo);
|
||||
} else if (atom == XCB->getAtom("_NET_WM_NAME")) {
|
||||
winInfo->updateWmName();
|
||||
newInnerId = winInfo->genInnerId(winInfo);
|
||||
} else if (atom == XCB->getAtom("_NET_WM_ICON")) {
|
||||
winInfo->updateIcon();
|
||||
} else if (atom == XCB->getAtom("_NET_WM_ALLOWED_ACTIONS")) {
|
||||
winInfo->updateWmAllowedActions();
|
||||
} else if (atom == XCB->getAtom("_MOTIF_WM_HINTS")) {
|
||||
winInfo->updateMotifWmHints();
|
||||
} else if (atom == XCB_ATOM_WM_CLASS) {
|
||||
winInfo->updateWmClass();
|
||||
newInnerId = winInfo->genInnerId(winInfo);
|
||||
needAttachOrDetach = true;
|
||||
} else if (atom == XCB->getAtom("_XEMBED_INFO")) {
|
||||
winInfo->updateHasXEmbedInfo();
|
||||
needAttachOrDetach = true;
|
||||
} else if (atom == XCB->getAtom("_NET_WM_WINDOW_TYPE")) {
|
||||
winInfo->updateWmWindowType();
|
||||
needAttachOrDetach = true;
|
||||
} else if (atom == XCB_ATOM_WM_TRANSIENT_FOR) {
|
||||
winInfo->updateHasWmTransientFor();
|
||||
needAttachOrDetach = true;
|
||||
}
|
||||
|
||||
if (!newInnerId.isEmpty() && winInfo->getUpdateCalled() && winInfo->getInnerId() != newInnerId) {
|
||||
// winInfo.innerId changed
|
||||
dock->detachWindow(winInfo);
|
||||
winInfo->setInnerId(newInnerId);
|
||||
needAttachOrDetach = true;
|
||||
}
|
||||
|
||||
if (needAttachOrDetach)
|
||||
dock->attachWindow(winInfo);
|
||||
|
||||
Entry *entry = dock->getEntryByWindowId(xid);
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
if (atom == XCB->getAtom("_NET_WM_STATE")) {
|
||||
entry->updateWindowInfos();
|
||||
} else if (atom == XCB->getAtom("_NET_WM_ICON")) {
|
||||
if (entry->getCurrentWindowInfo() == winInfo) {
|
||||
entry->updateIcon();
|
||||
}
|
||||
} else if (atom == XCB->getAtom("_NET_WM_NAME")) {
|
||||
if (entry->getCurrentWindowInfo() == winInfo) {
|
||||
entry->updateName();
|
||||
}
|
||||
entry->updateWindowInfos();
|
||||
} else if (atom == XCB->getAtom("_NET_WM_ALLOWED_ACTIONS")) {
|
||||
entry->updateMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void X11Manager::eventHandler(uint8_t type, void *event)
|
||||
{
|
||||
qInfo() << "eventHandler" << "type = " << type;
|
||||
switch (type) {
|
||||
case XCB_MAP_NOTIFY: // 17 注册新窗口
|
||||
qInfo() << "eventHandler: XCB_MAP_NOTIFY";
|
||||
break;
|
||||
case XCB_DESTROY_NOTIFY: // 19 销毁窗口
|
||||
qInfo() << "eventHandler: XCB_DESTROY_NOTIFY";
|
||||
break;
|
||||
case XCB_CONFIGURE_NOTIFY: // 22 窗口变化
|
||||
qInfo() << "eventHandler: XCB_CONFIGURE_NOTIFY";
|
||||
break;
|
||||
case XCB_PROPERTY_NOTIFY: // 28 窗口属性改变
|
||||
qInfo() << "eventHandler: XCB_PROPERTY_NOTIFY";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void X11Manager::addWindowLastConfigureEvent(XWindow xid, ConfigureEvent *event)
|
||||
{
|
||||
delWindowLastConfigureEvent(xid);
|
||||
|
||||
QMutexLocker locker(&mutex);
|
||||
QTimer *timer = new QTimer();
|
||||
timer->setInterval(configureNotifyDelay);
|
||||
windowLastConfigureEventMap[xid] = QPair(event, timer);
|
||||
}
|
||||
|
||||
QPair<ConfigureEvent *, QTimer *> X11Manager::getWindowLastConfigureEvent(XWindow xid)
|
||||
{
|
||||
QPair<ConfigureEvent *, QTimer *> ret;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (windowLastConfigureEventMap.find(xid) != windowLastConfigureEventMap.end())
|
||||
ret = windowLastConfigureEventMap[xid];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void X11Manager::delWindowLastConfigureEvent(XWindow xid)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
if (windowLastConfigureEventMap.find(xid) != windowLastConfigureEventMap.end()) {
|
||||
QPair<ConfigureEvent*, QTimer*> item = windowLastConfigureEventMap[xid];
|
||||
windowLastConfigureEventMap.remove(xid);
|
||||
delete item.first;
|
||||
item.second->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
77
src/modules/dock/x11manager.h
Normal file
77
src/modules/dock/x11manager.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef X11MANAGER_H
|
||||
#define X11MANAGER_H
|
||||
|
||||
#include "windowinfox.h"
|
||||
#include "xcbutils.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include <QTimer>
|
||||
|
||||
class Dock;
|
||||
|
||||
class X11Manager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit X11Manager(Dock *_dock, QObject *parent = nullptr);
|
||||
|
||||
WindowInfoX *findWindowByXid(XWindow xid);
|
||||
WindowInfoX *registerWindow(XWindow xid);
|
||||
void unregisterWindow(XWindow xid);
|
||||
|
||||
void handleClientListChanged();
|
||||
void handleActiveWindowChangedX();
|
||||
void listenRootWindowXEvent();
|
||||
void listenWindowXEvent(WindowInfoX *winInfo);
|
||||
|
||||
void handleRootWindowPropertyNotifyEvent(XCBAtom atom);
|
||||
void handleDestroyNotifyEvent(XWindow xid);
|
||||
void handleMapNotifyEvent(XWindow xid);
|
||||
void handleConfigureNotifyEvent(XWindow xid, int x, int y, int width, int height);
|
||||
void handlePropertyNotifyEvent(XWindow xid, XCBAtom atom);
|
||||
|
||||
void eventHandler(uint8_t type, void *event);
|
||||
void listenWindowEvent(WindowInfoX *winInfo);
|
||||
void listenXEventUseXlib();
|
||||
void listenXEventUseXCB();
|
||||
|
||||
signals:
|
||||
void needUpdateHideState(bool delay);
|
||||
|
||||
private:
|
||||
void addWindowLastConfigureEvent(XWindow xid, ConfigureEvent* event);
|
||||
QPair<ConfigureEvent*, QTimer*> getWindowLastConfigureEvent(XWindow xid);
|
||||
void delWindowLastConfigureEvent(XWindow xid);
|
||||
|
||||
QMap<XWindow, WindowInfoX *> windowInfoMap;
|
||||
Dock *dock;
|
||||
QMap<XWindow, QPair<ConfigureEvent*, QTimer*>> windowLastConfigureEventMap; // 手动回收ConfigureEvent和QTimer
|
||||
QMutex mutex;
|
||||
XWindow rootWindow; // 根窗口
|
||||
bool listenXEvent; // 监听X事件
|
||||
};
|
||||
|
||||
#endif // X11MANAGER_H
|
291
src/modules/launcher/category.cpp
Normal file
291
src/modules/launcher/category.cpp
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (C) 2022 ~ 2023 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* Maintainer: weizhixiang <weizhixiang@uniontech.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "category.h"
|
||||
|
||||
Category::Category()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Category::~Category()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString Category::getStr(Categorytype ty) {
|
||||
QMap<Categorytype, QString> ty2str = {
|
||||
{Categorytype::CategoryInternet, "Internet"},
|
||||
{Categorytype::CategoryChat, "Chat"},
|
||||
{Categorytype::CategoryMusic, "Music"},
|
||||
{Categorytype::CategoryVideo, "Video"},
|
||||
{Categorytype::CategoryGraphics, "Graphics"},
|
||||
{Categorytype::CategoryOffice, "Office"},
|
||||
{Categorytype::CategoryGame, "Game"},
|
||||
{Categorytype::CategoryReading, "Reading"},
|
||||
{Categorytype::CategoryDevelopment, "Development"},
|
||||
{Categorytype::CategorySystem, "System"},
|
||||
{Categorytype::CategoryOthers, "Others"},
|
||||
};
|
||||
return ty2str.find(ty) != ty2str.end() ? ty2str[ty] : "Others";
|
||||
}
|
||||
|
||||
QString Category::pinYin(Categorytype ty) {
|
||||
QMap<Categorytype, QString> ty2py = {
|
||||
{Categorytype::CategoryInternet, "wangluo"},
|
||||
{Categorytype::CategoryChat, "shejiaogoutong"},
|
||||
{Categorytype::CategoryMusic, "yinyuexinshang"},
|
||||
{Categorytype::CategoryVideo, "shipinbofang"},
|
||||
{Categorytype::CategoryGraphics, "tuxintuxiang"},
|
||||
{Categorytype::CategoryOffice, "bangongxuexi"},
|
||||
{Categorytype::CategoryGame, "youxiyule"},
|
||||
{Categorytype::CategoryReading, "yuedufanyi"},
|
||||
{Categorytype::CategoryDevelopment, "bianchengkaifai"},
|
||||
{Categorytype::CategorySystem, "xitongguanli"},
|
||||
{Categorytype::CategoryOthers, "qita"},
|
||||
};
|
||||
return ty2py.find(ty) != ty2py.end() ? ty2py[ty] : "qita";
|
||||
}
|
||||
|
||||
Categorytype Category::parseCategoryString(QString str) {
|
||||
QMap<QString, Categorytype> name2ty {
|
||||
{"internet", Categorytype::CategoryInternet},
|
||||
{"chat", Categorytype::CategoryChat},
|
||||
{"music", Categorytype::CategoryMusic},
|
||||
{"video", Categorytype::CategoryVideo},
|
||||
{"graphics", Categorytype::CategoryGraphics},
|
||||
{"office", Categorytype::CategoryOffice},
|
||||
{"game", Categorytype::CategoryGame},
|
||||
{"reading", Categorytype::CategoryReading},
|
||||
{"development", Categorytype::CategoryDevelopment},
|
||||
{"system", Categorytype::CategorySystem},
|
||||
{"others", Categorytype::CategoryOthers},
|
||||
};
|
||||
return name2ty.find(str) != name2ty.end() ? name2ty[str] : Categorytype::CategoryErr;
|
||||
}
|
||||
|
||||
QList<Categorytype> Category::parseXCategoryString(QString str) {
|
||||
QMultiMap<QString, Categorytype> xname2ty {
|
||||
{"2dgraphics", Categorytype::CategoryGraphics},
|
||||
{"3dgraphics", Categorytype::CategoryGraphics},
|
||||
{"accessibility", Categorytype::CategorySystem},
|
||||
{"accessories", Categorytype::CategoryOthers},
|
||||
{"actiongame", Categorytype::CategoryGame},
|
||||
{"advancedsettings", Categorytype::CategorySystem},
|
||||
{"adventuregame", Categorytype::CategoryGame},
|
||||
{"amusement", Categorytype::CategoryGame},
|
||||
{"applet", Categorytype::CategoryOthers},
|
||||
{"arcadegame", Categorytype::CategoryGame},
|
||||
{"archiving", Categorytype::CategorySystem},
|
||||
{"art", Categorytype::CategoryOffice},
|
||||
{"artificialintelligence", Categorytype::CategoryOffice},
|
||||
{"astronomy", Categorytype::CategoryOffice},
|
||||
{"audio", Categorytype::CategoryMusic},
|
||||
{"audiovideo", Categorytype::CategoryMusic},
|
||||
{"audiovideo", Categorytype::CategoryVideo},
|
||||
{"audiovideoediting", Categorytype::CategoryMusic},
|
||||
{"audiovideoediting", Categorytype::CategoryVideo},
|
||||
{"biology", Categorytype::CategoryOffice},
|
||||
{"blocksgame", Categorytype::CategoryGame},
|
||||
{"boardgame", Categorytype::CategoryGame},
|
||||
{"building", Categorytype::CategoryDevelopment},
|
||||
{"calculator", Categorytype::CategorySystem},
|
||||
{"calendar", Categorytype::CategorySystem},
|
||||
{"cardgame", Categorytype::CategoryGame},
|
||||
{"cd", Categorytype::CategoryMusic},
|
||||
{"chart", Categorytype::CategoryOffice},
|
||||
{"chat", Categorytype::CategoryChat},
|
||||
{"chemistry", Categorytype::CategoryOffice},
|
||||
{"clock", Categorytype::CategorySystem},
|
||||
{"compiz", Categorytype::CategorySystem},
|
||||
{"compression", Categorytype::CategorySystem},
|
||||
{"computerscience", Categorytype::CategoryOffice},
|
||||
{"consoleonly", Categorytype::CategoryOthers},
|
||||
{"contactmanagement", Categorytype::CategoryChat},
|
||||
{"core", Categorytype::CategoryOthers},
|
||||
{"debugger", Categorytype::CategoryDevelopment},
|
||||
{"desktopsettings", Categorytype::CategorySystem},
|
||||
{"desktoputility", Categorytype::CategorySystem},
|
||||
{"development", Categorytype::CategoryDevelopment},
|
||||
{"dialup", Categorytype::CategorySystem},
|
||||
{"dictionary", Categorytype::CategoryOffice},
|
||||
{"discburning", Categorytype::CategorySystem},
|
||||
{"documentation", Categorytype::CategoryOffice},
|
||||
{"editors", Categorytype::CategoryOthers},
|
||||
{"education", Categorytype::CategoryOffice},
|
||||
{"electricity", Categorytype::CategoryOffice},
|
||||
{"electronics", Categorytype::CategoryOffice},
|
||||
{"email", Categorytype::CategoryInternet},
|
||||
{"emulator", Categorytype::CategoryGame},
|
||||
{"engineering", Categorytype::CategorySystem},
|
||||
{"favorites", Categorytype::CategoryOthers},
|
||||
{"filemanager", Categorytype::CategorySystem},
|
||||
{"filesystem", Categorytype::CategorySystem},
|
||||
{"filetools", Categorytype::CategorySystem},
|
||||
{"filetransfer", Categorytype::CategoryInternet},
|
||||
{"finance", Categorytype::CategoryOffice},
|
||||
{"game", Categorytype::CategoryGame},
|
||||
{"geography", Categorytype::CategoryOffice},
|
||||
{"geology", Categorytype::CategoryOffice},
|
||||
{"geoscience", Categorytype::CategoryOthers},
|
||||
{"gnome", Categorytype::CategorySystem},
|
||||
{"gpe", Categorytype::CategoryOthers},
|
||||
{"graphics", Categorytype::CategoryGraphics},
|
||||
{"guidesigner", Categorytype::CategoryDevelopment},
|
||||
{"hamradio", Categorytype::CategoryOffice},
|
||||
{"hardwaresettings", Categorytype::CategorySystem},
|
||||
{"ide", Categorytype::CategoryDevelopment},
|
||||
{"imageprocessing", Categorytype::CategoryGraphics},
|
||||
{"instantmessaging", Categorytype::CategoryChat},
|
||||
{"internet", Categorytype::CategoryInternet},
|
||||
{"ircclient", Categorytype::CategoryChat},
|
||||
{"kde", Categorytype::CategorySystem},
|
||||
{"kidsgame", Categorytype::CategoryGame},
|
||||
{"literature", Categorytype::CategoryOffice},
|
||||
{"logicgame", Categorytype::CategoryGame},
|
||||
{"math", Categorytype::CategoryOffice},
|
||||
{"medicalsoftware", Categorytype::CategoryOffice},
|
||||
{"meteorology", Categorytype::CategoryOthers},
|
||||
{"midi", Categorytype::CategoryMusic},
|
||||
{"mixer", Categorytype::CategoryMusic},
|
||||
{"monitor", Categorytype::CategorySystem},
|
||||
{"motif", Categorytype::CategoryOthers},
|
||||
{"multimedia", Categorytype::CategoryVideo},
|
||||
{"music", Categorytype::CategoryMusic},
|
||||
{"network", Categorytype::CategoryInternet},
|
||||
{"news", Categorytype::CategoryReading},
|
||||
{"numericalanalysis", Categorytype::CategoryOffice},
|
||||
{"ocr", Categorytype::CategoryGraphics},
|
||||
{"office", Categorytype::CategoryOffice},
|
||||
{"p2p", Categorytype::CategoryInternet},
|
||||
{"packagemanager", Categorytype::CategorySystem},
|
||||
{"panel", Categorytype::CategorySystem},
|
||||
{"pda", Categorytype::CategorySystem},
|
||||
{"photography", Categorytype::CategoryGraphics},
|
||||
{"physics", Categorytype::CategoryOffice},
|
||||
{"pim", Categorytype::CategoryOthers},
|
||||
{"player", Categorytype::CategoryMusic},
|
||||
{"player", Categorytype::CategoryVideo},
|
||||
{"playonlinux", Categorytype::CategoryOthers},
|
||||
{"presentation", Categorytype::CategoryOffice},
|
||||
{"printing", Categorytype::CategoryOffice},
|
||||
{"profiling", Categorytype::CategoryDevelopment},
|
||||
{"projectmanagement", Categorytype::CategoryOffice},
|
||||
{"publishing", Categorytype::CategoryOffice},
|
||||
{"puzzlegame", Categorytype::CategoryGame},
|
||||
{"rastergraphics", Categorytype::CategoryGraphics},
|
||||
{"recorder", Categorytype::CategoryMusic},
|
||||
{"recorder", Categorytype::CategoryVideo},
|
||||
{"remoteaccess", Categorytype::CategorySystem},
|
||||
{"revisioncontrol", Categorytype::CategoryDevelopment},
|
||||
{"robotics", Categorytype::CategoryOffice},
|
||||
{"roleplaying", Categorytype::CategoryGame},
|
||||
{"scanning", Categorytype::CategoryOffice},
|
||||
{"science", Categorytype::CategoryOffice},
|
||||
{"screensaver", Categorytype::CategoryOthers},
|
||||
{"sequencer", Categorytype::CategoryMusic},
|
||||
{"settings", Categorytype::CategorySystem},
|
||||
{"security", Categorytype::CategorySystem},
|
||||
{"simulation", Categorytype::CategoryGame},
|
||||
{"sportsgame", Categorytype::CategoryGame},
|
||||
{"spreadsheet", Categorytype::CategoryOffice},
|
||||
{"strategygame", Categorytype::CategoryGame},
|
||||
{"system", Categorytype::CategorySystem},
|
||||
{"systemsettings", Categorytype::CategorySystem},
|
||||
{"technical", Categorytype::CategoryOthers},
|
||||
{"telephony", Categorytype::CategorySystem},
|
||||
{"telephonytools", Categorytype::CategorySystem},
|
||||
{"terminalemulator", Categorytype::CategorySystem},
|
||||
{"texteditor", Categorytype::CategoryOffice},
|
||||
{"texttools", Categorytype::CategoryOffice},
|
||||
{"transiation", Categorytype::CategoryDevelopment},
|
||||
{"translation", Categorytype::CategoryReading},
|
||||
{"trayicon", Categorytype::CategorySystem},
|
||||
{"tuner", Categorytype::CategoryMusic},
|
||||
{"tv", Categorytype::CategoryVideo},
|
||||
{"utility", Categorytype::CategorySystem},
|
||||
{"vectorgraphics", Categorytype::CategoryGraphics},
|
||||
{"video", Categorytype::CategoryVideo},
|
||||
{"videoconference", Categorytype::CategoryInternet},
|
||||
{"viewer", Categorytype::CategoryGraphics},
|
||||
{"webbrowser", Categorytype::CategoryInternet},
|
||||
{"webdevelopment", Categorytype::CategoryDevelopment},
|
||||
{"wine", Categorytype::CategoryOthers},
|
||||
{"wine-programs-accessories", Categorytype::CategoryOthers},
|
||||
{"wordprocessor", Categorytype::CategoryOffice},
|
||||
{"x-alsa", Categorytype::CategoryMusic},
|
||||
{"x-bible", Categorytype::CategoryReading},
|
||||
{"x-bluetooth", Categorytype::CategorySystem},
|
||||
{"x-debian-applications-emulators", Categorytype::CategoryGame},
|
||||
{"x-digital_processing", Categorytype::CategorySystem},
|
||||
{"x-enlightenment", Categorytype::CategorySystem},
|
||||
{"x-geeqie", Categorytype::CategoryGraphics},
|
||||
{"x-gnome-networksettings", Categorytype::CategorySystem},
|
||||
{"x-gnome-personalsettings", Categorytype::CategorySystem},
|
||||
{"x-gnome-settings-panel", Categorytype::CategorySystem},
|
||||
{"x-gnome-systemsettings", Categorytype::CategorySystem},
|
||||
{"x-gnustep", Categorytype::CategorySystem},
|
||||
{"x-islamic-software", Categorytype::CategoryReading},
|
||||
{"x-jack", Categorytype::CategoryMusic},
|
||||
{"x-kde-edu-misc", Categorytype::CategoryReading},
|
||||
{"x-kde-internet", Categorytype::CategorySystem},
|
||||
{"x-kde-more", Categorytype::CategorySystem},
|
||||
{"x-kde-utilities-desktop", Categorytype::CategorySystem},
|
||||
{"x-kde-utilities-file", Categorytype::CategorySystem},
|
||||
{"x-kde-utilities-peripherals", Categorytype::CategorySystem},
|
||||
{"x-kde-utilities-pim", Categorytype::CategorySystem},
|
||||
{"x-lxde-settings", Categorytype::CategorySystem},
|
||||
{"x-mandriva-office-publishing", Categorytype::CategoryOthers},
|
||||
{"x-mandrivalinux-internet-other", Categorytype::CategorySystem},
|
||||
{"x-mandrivalinux-office-other", Categorytype::CategoryOffice},
|
||||
{"x-mandrivalinux-system-archiving-backup", Categorytype::CategorySystem},
|
||||
{"x-midi", Categorytype::CategoryMusic},
|
||||
{"x-misc", Categorytype::CategorySystem},
|
||||
{"x-multitrack", Categorytype::CategoryMusic},
|
||||
{"x-novell-main", Categorytype::CategorySystem},
|
||||
{"x-quran", Categorytype::CategoryReading},
|
||||
{"x-red-hat-base", Categorytype::CategorySystem},
|
||||
{"x-red-hat-base-only", Categorytype::CategorySystem},
|
||||
{"x-red-hat-extra", Categorytype::CategorySystem},
|
||||
{"x-red-hat-serverconfig", Categorytype::CategorySystem},
|
||||
{"x-religion", Categorytype::CategoryReading},
|
||||
{"x-sequencers", Categorytype::CategoryMusic},
|
||||
{"x-sound", Categorytype::CategoryMusic},
|
||||
{"x-sun-supported", Categorytype::CategorySystem},
|
||||
{"x-suse-backup", Categorytype::CategorySystem},
|
||||
{"x-suse-controlcenter-lookandfeel", Categorytype::CategorySystem},
|
||||
{"x-suse-controlcenter-system", Categorytype::CategorySystem},
|
||||
{"x-suse-core", Categorytype::CategorySystem},
|
||||
{"x-suse-core-game", Categorytype::CategoryGame},
|
||||
{"x-suse-core-office", Categorytype::CategoryOffice},
|
||||
{"x-suse-sequencer", Categorytype::CategoryMusic},
|
||||
{"x-suse-yast", Categorytype::CategorySystem},
|
||||
{"x-suse-yast-high_availability", Categorytype::CategorySystem},
|
||||
{"x-synthesis", Categorytype::CategorySystem},
|
||||
{"x-turbolinux-office", Categorytype::CategoryOffice},
|
||||
{"x-xfce", Categorytype::CategorySystem},
|
||||
{"x-xfce-toplevel", Categorytype::CategorySystem},
|
||||
{"x-xfcesettingsdialog", Categorytype::CategorySystem},
|
||||
{"x-ximian-main", Categorytype::CategorySystem},
|
||||
};
|
||||
|
||||
return {xname2ty.values(str)};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user