Compare commits

..

No commits in common. "master" and "refactor" have entirely different histories.

1052 changed files with 12226 additions and 91902 deletions

View File

@ -38,12 +38,12 @@ BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
@ -68,6 +68,10 @@ PPIndentWidth: 2
AlignAfterOpenBracket: Align
AlwaysBreakTemplateDeclarations: true
# Ideally we should also allow less short function in a single line, but
# clang-format does not handle that.
AllowShortFunctionsOnASingleLine: Inline
# As clang-format 13 can regroup includes we enable this feature.
# basically according to https://wiki.qt.io/Coding_Conventions#Including_headers
# and https://github.com/linuxdeepin/deepin-styleguide
@ -106,7 +110,7 @@ IncludeCategories:
- Regex: '^<'
Priority: 3
IncludeIsMainRegex: '((T|t)est)?$'
SortIncludes: CaseSensitive
SortIncludes: true
# macros for which the opening brace stays attached.
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
@ -136,8 +140,6 @@ SpaceBeforeCpp11BracedList: false
AllowAllArgumentsOnNextLine: false
AllowShortLambdasOnASingleLine: Empty
AllowShortFunctionsOnASingleLine: Empty
AllowAllParametersOfDeclarationOnNextLine: false
AlignTrailingComments: true
BinPackArguments: false
BinPackParameters: false

11
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gitsubmodule" # See documentation for possible values
directory: "/"
schedule:
interval: "daily"

View File

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

View File

@ -1,87 +0,0 @@
name: Build qwlroots on Arch Linux (independent)
on:
push:
paths:
- 'qwlroots/**'
- '.github/workflows/qwlroots-archlinux-build.yml'
pull_request:
paths:
- 'qwlroots/**'
- '.github/workflows/qwlroots-archlinux-build.yml'
jobs:
container:
runs-on: ubuntu-latest
container: archlinux:latest
steps:
- uses: actions/checkout@v4
- name: Run in container
run: |
pacman-key --init
pacman -Syu --noconfirm
- name: Install dependencies
run: |
pacman -Syu --noconfirm qt6-base cmake pkgconfig wlroots0.19 pixman wayland-protocols wlr-protocols
pacman -Syu --noconfirm clang ninja base-devel git
- name: Configure and build qwlroots
working-directory: qwlroots
run: |
echo "Working directory:" $PWD
cmake --preset ci
cmake --build --preset ci
- name: Install qwlroots to staging directory
working-directory: qwlroots
run: |
echo "Installing qwlroots to staging directory..."
mkdir -p /tmp/qwlroots-install
DESTDIR=/tmp/qwlroots-install cmake --install build
echo "✅ qwlroots installed to staging directory"
echo "Installed files:"
find /tmp/qwlroots-install -type f | head -20
echo "Total files installed: $(find /tmp/qwlroots-install -type f | wc -l)"
- name: Create qwlroots installation package
run: |
cd /tmp/qwlroots-install
# Install zip if not available
pacman -Syu --noconfirm zip
# Create package info
echo "Creating package info..."
cat > PACKAGE_INFO.txt << EOF
Package: qwlroots-archlinux-build
Version: $(date +%Y%m%d-%H%M%S)
Architecture: x86_64
Built-on: Arch Linux
CMake-Config: Default configuration
Installation Instructions:
1. Extract this package to /
2. Run: sudo ldconfig (if libraries are included)
3. Ensure dependencies are installed on target system
Files included in this package:
EOF
find . -type f | sort >> PACKAGE_INFO.txt
# Create the zip package
zip -r /tmp/qwlroots-archlinux-$(date +%Y%m%d-%H%M%S).zip .
echo "✅ qwlroots installation package created"
ls -la /tmp/qwlroots-archlinux-*.zip
- name: Upload qwlroots ArchLinux build artifacts
uses: actions/upload-artifact@v4
with:
name: qwlroots-archlinux-build
path: "/tmp/qwlroots-archlinux-*.zip"
if-no-files-found: error
retention-days: 30

View File

@ -1,59 +0,0 @@
name: Build qwlroots on Debian unstable (independent)
on:
push:
paths:
- 'qwlroots/**'
- '.github/workflows/qwlroots-debian-build.yml'
pull_request:
paths:
- 'qwlroots/**'
- '.github/workflows/qwlroots-debian-build.yml'
jobs:
container:
runs-on: ubuntu-latest
container: debian:unstable
steps:
- uses: actions/checkout@v4
- name: Install build dependencies
working-directory: qwlroots
run: |
# Configure apt sources for unstable
echo "deb http://deb.debian.org/debian unstable main" > /etc/apt/sources.list
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list
apt-get update
apt-get install -y devscripts equivs
# Add deepin community repository to install wlr-protocols
echo "deb [trusted=yes] https://community-packages.deepin.com/beige/ crimson main commercial community" > /etc/apt/sources.list.d/deepin-community.list
# Update package lists (ignore signature errors for this temporary repo)
apt-get update --allow-unauthenticated
# Install wlr-protocols package directly
apt-get install -y --allow-unauthenticated wlr-protocols
# Remove deepin repository to avoid system pollution
rm -f /etc/apt/sources.list.d/deepin-community.list
apt-get update
# Install other build dependencies from control file
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
- name: Build qwlroots deb package
working-directory: qwlroots
run: |
dpkg-buildpackage -uc -us -b
echo "✅ qwlroots deb package built successfully!"
ls -la ../*.deb
- name: Upload qwlroots deb packages as artifacts
uses: actions/upload-artifact@v4
with:
name: qwlroots-deb-packages
path: "*.deb"
if-no-files-found: error
retention-days: 30

View File

@ -1,129 +0,0 @@
name: Build treeland on Arch Linux
# This workflow builds treeland with merged waylib and qwlroots code
# Dependencies are based on the official ArchLinux PKGBUILD plus
# additional dependencies from the integrated waylib and qwlroots code
# treeland-protocols-git is installed from AUR
on:
push:
pull_request:
jobs:
container:
runs-on: ubuntu-latest
container: archlinux:latest
steps:
- name: Run in container
run: |
cat /etc/pacman.d/mirrorlist
pacman-key --init
pacman --noconfirm --noprogressbar -Syu
- name: Install base dependencies
run: |
pacman -Syu --noconfirm --noprogressbar base-devel git cmake ninja pkgconfig clang make
pacman -Syu --noconfirm --noprogressbar fakeroot meson sudo
- name: Install Qt6 dependencies
run: |
# Qt6 dependencies matching qwlroots and waylib builds
pacman -Syu --noconfirm --noprogressbar qt6-base qt6-declarative qt6-wayland qt6-tools
- name: Install graphics and wayland dependencies
run: |
# Core graphics and wayland dependencies (matching qwlroots and waylib builds)
pacman -Syu --noconfirm --noprogressbar pixman vulkan-headers wayland wayland-protocols wlr-protocols
pacman -Syu --noconfirm --noprogressbar wlroots0.19 libinput pam systemd-libs jemalloc gcc-libs glibc
- name: Install additional waylib/qwlroots dependencies
run: |
# Additional dependencies from waylib and qwlroots build configs
pacman -Syu --noconfirm --noprogressbar libdrm xcb-util-errors libxdmcp
- name: Install DTK dependencies
run: |
# Try to install DTK from available packages
# If not available, the build will proceed without them (may fail)
pacman -Syu --noconfirm --noprogressbar dtk6core dtk6declarative dtk6systemsettings
- name: Install DDM dependencies
run: |
# Try to install DDM from available packages
pacman -Syu --noconfirm --noprogressbar ddm
- name: Build and Install treeland-protocols
run: |
echo "Building treeland-protocols from source..."
git clone https://github.com/linuxdeepin/treeland-protocols.git --depth 1
cd treeland-protocols
cmake -B build \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE=Release
cmake --build build
cmake --install build
echo "✅ treeland-protocols built and installed from source"
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure and Build treeland with ci preset
run: |
echo "Working directory:" $PWD
echo "Configuring treeland with merged waylib and qwlroots code..."
cmake --preset ci
cmake --build --preset ci
echo "✅ treeland built successfully with merged waylib and qwlroots code!"
- name: Install treeland to staging directory
run: |
echo "Installing treeland to staging directory..."
mkdir -p /tmp/treeland-install
DESTDIR=/tmp/treeland-install cmake --install build
echo "✅ treeland installed to staging directory"
echo "Installed files:"
find /tmp/treeland-install -type f | head -20
echo "Total files installed: $(find /tmp/treeland-install -type f | wc -l)"
- name: Create treeland installation package
run: |
cd /tmp/treeland-install
# Install zip if not available
pacman -Syu --noconfirm zip
# Create package info
echo "Creating package info..."
cat > PACKAGE_INFO.txt << EOF
Package: treeland-archlinux-build
Version: $(date +%Y%m%d-%H%M%S)
Architecture: x86_64
Built-on: Arch Linux
Built-with: merged waylib and qwlroots code
CMake-Config: -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib
Installation Instructions:
1. Extract this package to /
2. Run: sudo ldconfig (if libraries are included)
3. Ensure dependencies are installed on target system
Files included in this package:
EOF
find . -type f | sort >> PACKAGE_INFO.txt
# Create the zip package
zip -r /tmp/treeland-archlinux-$(date +%Y%m%d-%H%M%S).zip .
echo "✅ treeland installation package created"
ls -la /tmp/treeland-archlinux-*.zip
- name: Upload treeland ArchLinux build artifacts
uses: actions/upload-artifact@v4
with:
name: treeland-archlinux-build
path: "/tmp/treeland-archlinux-*.zip"
if-no-files-found: error
retention-days: 30

View File

@ -1,100 +0,0 @@
name: Build waylib on Arch Linux (independent)
on:
push:
paths:
- 'waylib/**'
- 'qwlroots/**'
- '.github/workflows/waylib-archlinux-build.yml'
pull_request:
paths:
- 'waylib/**'
- 'qwlroots/**'
- '.github/workflows/waylib-archlinux-build.yml'
jobs:
container:
runs-on: ubuntu-latest
container: archlinux:latest
steps:
- name: Run in container
run: |
cat /etc/pacman.d/mirrorlist
pacman-key --init
pacman --noconfirm --noprogressbar -Syu
- name: Install dependencies
run: |
pacman -Syu --noconfirm --noprogressbar base-devel qt6-base qt6-declarative cmake pkgconfig pixman vulkan-headers wlroots0.19 wayland-protocols wlr-protocols git
pacman -Syu --noconfirm --noprogressbar clang ninja make
pacman -Syu --noconfirm --noprogressbar fakeroot meson sudo
- uses: actions/checkout@v4
with:
submodules: true
- name: Create qwlroots symlink for waylib
run: |
cd waylib
ln -sf ../qwlroots qwlroots
echo "✅ Created symlink: waylib/qwlroots -> ../qwlroots"
ls -la qwlroots
- name: Configure and Build waylib with ci preset
working-directory: waylib
run: |
echo "Working directory:" $PWD
cmake --preset ci -DWITH_SUBMODULE_QWLROOTS=ON
cmake --build --preset ci
- name: Install waylib to staging directory
working-directory: waylib
run: |
echo "Installing waylib to staging directory..."
mkdir -p /tmp/waylib-install
DESTDIR=/tmp/waylib-install cmake --install build
echo "✅ waylib installed to staging directory"
echo "Installed files:"
find /tmp/waylib-install -type f | head -20
echo "Total files installed: $(find /tmp/waylib-install -type f | wc -l)"
- name: Create waylib installation package
run: |
cd /tmp/waylib-install
# Install zip if not available
pacman -Syu --noconfirm zip
# Create package info
echo "Creating package info..."
cat > PACKAGE_INFO.txt << EOF
Package: waylib-archlinux-build
Version: $(date +%Y%m%d-%H%M%S)
Architecture: x86_64
Built-on: Arch Linux
Built-with: qwlroots submodule enabled
CMake-Config: -DWITH_SUBMODULE_QWLROOTS=ON
Installation Instructions:
1. Extract this package to /
2. Run: sudo ldconfig (if libraries are included)
3. Ensure dependencies are installed on target system
Files included in this package:
EOF
find . -type f | sort >> PACKAGE_INFO.txt
# Create the zip package
zip -r /tmp/waylib-archlinux-$(date +%Y%m%d-%H%M%S).zip .
echo "✅ waylib installation package created"
ls -la /tmp/waylib-archlinux-*.zip
- name: Upload waylib ArchLinux build artifacts
uses: actions/upload-artifact@v4
with:
name: waylib-archlinux-build
path: "/tmp/waylib-archlinux-*.zip"
if-no-files-found: error
retention-days: 30

View File

@ -1,84 +0,0 @@
name: Build waylib on Debian unstable (independent)
on:
push:
paths:
- 'waylib/**'
- 'qwlroots/**'
- '.github/workflows/waylib-debian-build.yml'
pull_request:
paths:
- 'waylib/**'
- 'qwlroots/**'
- '.github/workflows/waylib-debian-build.yml'
jobs:
container:
runs-on: ubuntu-latest
container: debian:unstable
steps:
- uses: actions/checkout@v4
- name: Build qwlroots first
working-directory: qwlroots
run: |
# Configure apt sources for unstable
echo "deb http://deb.debian.org/debian unstable main" > /etc/apt/sources.list
echo "deb http://deb.debian.org/debian sid main" >> /etc/apt/sources.list
apt-get update
apt-get install -y devscripts equivs
# Add deepin community repository to install wlr-protocols
echo "deb [trusted=yes] https://community-packages.deepin.com/beige/ crimson main commercial community" > /etc/apt/sources.list.d/deepin-community.list
# Update package lists (ignore signature errors for this temporary repo)
apt-get update --allow-unauthenticated
# Install wlr-protocols package directly
apt-get install -y --allow-unauthenticated wlr-protocols
# Remove deepin repository to avoid system pollution
rm -f /etc/apt/sources.list.d/deepin-community.list
apt-get update
# Install other build dependencies for qwlroots
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
# Build qwlroots deb package
dpkg-buildpackage -uc -us -b
echo "✅ qwlroots deb package built successfully!"
ls -la ../*.deb
- name: Install qwlroots deb package
run: |
# Install the built qwlroots package
dpkg -i qwlroots*.deb || apt-get install -f -y
echo "✅ qwlroots package installed!"
- name: Build waylib deb package
working-directory: waylib
run: |
# Install remaining build dependencies for waylib
apt-get install -y devscripts equivs
# Install waylib build dependencies (qwlroots is now available from the installed deb)
mk-build-deps --install --remove --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
# Build waylib with submodule disabled (use system qwlroots)
# Modify debian/rules to disable submodule
sed -i 's/-DCMAKE_INSTALL_PREFIX=\/usr/-DCMAKE_INSTALL_PREFIX=\/usr -DWITH_SUBMODULE_QWLROOTS=OFF/' debian/rules
echo "Modified debian/rules to disable qwlroots submodule:"
cat debian/rules
dpkg-buildpackage -uc -us -b
echo "✅ waylib deb package built successfully!"
ls -la ../*.deb
- name: Upload waylib deb packages as artifacts
uses: actions/upload-artifact@v4
with:
name: waylib-deb-packages
path: "*.deb"
if-no-files-found: error
retention-days: 30

5
.gitignore vendored
View File

@ -1,7 +1,6 @@
.vscode/
.cache/
build*/
.qtcreator/
*.user
@ -50,7 +49,3 @@ debian/files
debian/*.substvars
debian/*.debhelper.log
obj-*-linux-gnu/
# ai
.cursor
.specstory

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "waylib"]
path = waylib
url = https://github.com/vioken/waylib

View File

@ -1,26 +0,0 @@
[main]
host = https://www.transifex.com
[o:linuxdeepin:p:treeland:r:f56f82288bfe7a231b1be25f7b0cb008]
file_filter = translations/treeland.<lang>.ts
source_file = translations/treeland.en_US.ts
source_lang = en_US
type = QT
[o:linuxdeepin:p:treeland:r:b675317802ed042606e0660179b6b04f]
file_filter = src/plugins/lockscreen/translations/lockscreen.<lang>.ts
source_file = src/plugins/lockscreen/translations/lockscreen.en_US.ts
source_lang = en_US
type = QT
[o:linuxdeepin:p:treeland:r:7309e9da01b4b7fbf5c2ac9c2a2d23a6]
file_filter = src/plugins/multitaskview/translations/multitaskview.<lang>.ts
source_file = src/plugins/multitaskview/translations/multitaskview.en_US.ts
source_lang = en_US
type = QT
[o:linuxdeepin:p:treeland:r:1eff66bc82bf8f288b9c56e8c724ea20]
file_filter = examples/test_set_treeland_wallpaper/translations/wallpaper.<lang>.ts
source_file = examples/test_set_treeland_wallpaper/translations/wallpaper.en_US.ts
source_lang = en_US
type = QT

View File

@ -1,23 +0,0 @@
filters:
- filter_type: file
source_file: translations/treeland.en_US.ts
file_format: QT
source_language: en_US
translation_files_expression: translations/treeland.<lang>.ts
- filter_type: file
source_file: src/plugins/lockscreen/translations/lockscreen.en_US.ts
file_format: QT
source_language: en_US
translation_files_expression: src/plugins/lockscreen/translations/lockscreen.<lang>.ts
- filter_type: file
source_file: src/plugins/multitaskview/translations/multitaskview.en_US.ts
file_format: QT
source_language: en_US
translation_files_expression: src/plugins/multitaskview/translations/multitaskview.<lang>.ts
- filter_type: file
source_file: examples/test_set_treeland_wallpaper/translations/wallpaper.en_US.ts
file_format: QT
source_language: en_US
translation_files_expression: examples/test_set_treeland_wallpaper/translations/wallpaper.<lang>.ts
settings:
pr_branch_name: transifex_update_<br_unique_id>

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.25.0)
project(Treeland
VERSION 0.7.0
VERSION 0.2.2
LANGUAGES CXX C)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
@ -14,50 +14,25 @@ include(GNUInstallDirs)
# Macros
include(FeatureSummary)
include(cmake/DefineTarget.cmake)
option(WITH_SUBMODULE_WAYLIB "Use the waylib from git submodule" ON)
option(WITH_SUBMODULE_WAYLIB "Use the waylib from git submodule" OFF)
add_feature_info(submodule_waylib WITH_SUBMODULE_WAYLIB "Use waylib from submodule")
option(ADDRESS_SANITIZER "Enable address sanitizer" OFF)
option(ADDRESS_SANITIZER "Enable address sanitize" OFF)
add_feature_info(ASanSupport ADDRESS_SANITIZER "https://github.com/google/sanitizers/wiki/AddressSanitizer")
option(BUILD_TREELAND_EXAMPLES "Build clients demo to test treeland" OFF)
option(BUILD_TEST_CLIENTS "Build clients demo to test treeland" OFF)
add_feature_info(DemoClents BUILD_TEST_CLIENTS "clients demo for testing")
option(DISABLE_DDM "Disable DDM and greeter" OFF)
if (DISABLE_DDM)
add_compile_definitions("DISABLE_DDM")
endif()
# Alternative lock mechanism: Wayland ext-session-lock
option(EXT_SESSION_LOCK_V1 "Enable Wayland ext-session-lock support (alternative to DDM)" ON)
add_feature_info(ext_session_lock_v1 EXT_SESSION_LOCK_V1 "Enable ext-session-lock-v1 protocol support in Treeland")
if (EXT_SESSION_LOCK_V1)
add_compile_definitions("EXT_SESSION_LOCK_V1")
endif()
# Heads-up if both are enabled: ext-session-lock is intended as an alternative to DDM
if (NOT EXT_SESSION_LOCK_V1 AND DISABLE_DDM)
message(WARNING "no ext-session-lock support and no DDM, treeland will not have session locking ability.")
endif()
if (ADDRESS_SANITIZER)
add_compile_options(-fsanitize=address -fno-optimize-sibling-calls -fno-omit-frame-pointer)
add_link_options(-fsanitize=address)
endif()
# NOTE: Qt keywords conflict with wlroots. but dtksystemsettings still uses it.
# add_definitions("-DQT_NO_KEYWORDS")
# NOTE: Enable Qt logging with context.
add_definitions("-DQT_MESSAGELOGCONTEXT")
set(LOCAL_QML_IMPORT_PATH "${PROJECT_BINARY_DIR}/qt/qml")
if(WITH_SUBMODULE_WAYLIB)
set(WITH_SUBMODULE_QWLROOTS ON)
include(${CMAKE_CURRENT_SOURCE_DIR}/qwlroots/cmake/WaylandScannerHelpers.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/waylib/qwlroots/cmake/WaylandScannerHelpers.cmake)
add_subdirectory(waylib)
list(APPEND LOCAL_QML_IMPORT_PATH "${PROJECT_BINARY_DIR}/waylib/src/server")
else()
@ -68,55 +43,24 @@ set(QML_IMPORT_PATH "${LOCAL_QML_IMPORT_PATH}" CACHE STRING "For LSP" FORCE)
# PKG-CONFIG
find_package(PkgConfig REQUIRED)
find_package(Qt6 CONFIG REQUIRED Core DBus Gui Qml Quick QuickControls2 LinguistTools Test QuickTest)
pkg_check_modules(WLROOTS REQUIRED IMPORTED_TARGET wlroots-0.19)
qt_standard_project_setup(REQUIRES 6.8)
qt_standard_project_setup(REQUIRES 6.6)
# Set constants
set(TREELAND_DATA_DIR "${CMAKE_INSTALL_DATADIR}/treeland/" CACHE PATH "treeland data install directory")
set(TREELAND_COMPONENTS_TRANSLATION_DIR "${TREELAND_DATA_DIR}/translations" CACHE PATH "Components translations directory")
set(TREELAND_PLUGINS_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib/plugins" CACHE PATH "treeland plugins output directory")
set(TREELAND_PLUGINS_INSTALL_PATH "${CMAKE_INSTALL_LIBDIR}/treeland/plugins" CACHE PATH "treeland plugins install directory")
GNUInstallDirs_get_absolute_install_dir(
TREELAND_FULL_DATA_DIR
TREELAND_DATA_DIR
DATADIR
)
GNUInstallDirs_get_absolute_install_dir(
TREELAND_FULL_PLUGINS_INSTALL_PATH
TREELAND_PLUGINS_INSTALL_PATH
LIBDIR
)
GNUInstallDirs_get_absolute_install_dir(
TREELAND_FULL_COMPONENTS_TRANSLATION_DIR
TREELAND_COMPONENTS_TRANSLATION_DIR
DATADIR
)
set(COMPONENTS_TRANSLATION_DIR "${TREELAND_DATA_DIR}/translations" CACHE PATH "Components translations directory")
GNUInstallDirs_get_absolute_install_dir(TREELAND_FULL_DATA_DIR TREELAND_DATA_DIR DATADIR)
add_compile_definitions("TREELAND_DATA_DIR=\"${TREELAND_FULL_DATA_DIR}\"")
# NOTE:: remove force assert before stable version
add_compile_definitions("QT_FORCE_ASSERTS")
add_compile_definitions("TREELAND_PLUGINS_INSTALL_PATH=\"${TREELAND_FULL_PLUGINS_INSTALL_PATH}\"")
add_compile_definitions("TREELAND_PLUGINS_OUTPUT_PATH=\"${TREELAND_PLUGINS_OUTPUT_PATH}\"")
add_compile_definitions("TREELAND_COMPONENTS_TRANSLATION_DIR=\"${TREELAND_FULL_COMPONENTS_TRANSLATION_DIR}\"")
set(PROJECT_RESOURCES_DIR "${CMAKE_SOURCE_DIR}/misc")
enable_testing(true)
add_subdirectory(src)
add_subdirectory(misc)
add_subdirectory(tests)
if (BUILD_TREELAND_EXAMPLES)
add_subdirectory(examples)
if (BUILD_TEST_CLIENTS)
add_subdirectory(tests)
endif()
# Display feature summary

View File

@ -12,7 +12,13 @@
"displayName": "Default Config",
"description": "Default build using Ninja generator",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build"
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"WITH_SUBMODULE_WAYLIB": {
"type": "BOOL",
"value": "OFF"
}
}
},
{
"name": "clang",
@ -21,51 +27,41 @@
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"WITH_SUBMODULE_WAYLIB": {
"type": "BOOL",
"value": "OFF"
},
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++"
}
},
{
"name": "ci",
"displayName": "CI Build Config",
"description": "Build configuration with warnings as errors",
"name": "submodule",
"displayName": "use submodule",
"description": "Default build using Ninja generator with git submodule",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_CXX_FLAGS": "-Wall -Wextra -Werror -Wno-stringop-overflow",
"CMAKE_C_FLAGS": "-Wall -Wextra -Werror -Wno-stringop-overflow"
"WITH_SUBMODULE_WAYLIB": {
"type": "BOOL",
"value": "ON"
}
}
},
{
"name": "deb",
"displayName": "Debian Package Build Config",
"description": "Build configuration for Debian packaging with examples enabled",
"name": "submodule-with-clang",
"displayName": "use submodule with clang",
"description": "Default build using Ninja generator with git submodule",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_C_COMPILER": "gcc",
"CMAKE_CXX_COMPILER": "g++",
"CMAKE_CXX_FLAGS": "-Wall -Wextra -Werror -Wno-stringop-overflow",
"CMAKE_C_FLAGS": "-Wall -Wextra -Werror -Wno-stringop-overflow",
"BUILD_TREELAND_EXAMPLES": "ON"
"WITH_SUBMODULE_WAYLIB":{
"type": "BOOL",
"value": "ON"
},
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++"
}
}
],
"buildPresets": [
{
"name": "default",
"configurePreset": "default"
},
{
"name": "clang",
"configurePreset": "clang"
},
{
"name": "ci",
"configurePreset": "ci"
},
{
"name": "deb",
"configurePreset": "deb"
}
]
}

View File

@ -1 +0,0 @@
../waylib/LICENSES/HPND.txt

View File

@ -1,8 +0,0 @@
Licensees holding valid commercial Qt licenses may use this software in
accordance with the the terms contained in a written agreement between
you and The Qt Company. Alternatively, the terms and conditions that were
accepted by the licensee when buying and/or downloading the
software do apply.
For the latest licensing terms and conditions, see https://www.qt.io/terms-conditions.
For further information use the contact form at https://www.qt.io/contact-us.

View File

@ -1,23 +0,0 @@
MIT License
Copyright (c) 2017, 2018 Drew DeVault
Copyright (c) 2014 Jari Vetoniemi
Copyright (c) 2023 The wlroots contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

133
README.md
View File

@ -1,68 +1,107 @@
# Treeland
## INTRODUCTION
treeland is a wayland compositor based on wlroots and QtQuick, designed to provide efficient and flexible graphical interface support.
DDM is a fork of SDDM. And use single compositor and session management functionality.
## Dependencies
SDDM is a modern display manager for X11 and Wayland sessions aiming to
be fast, simple and beautiful.
It uses modern technologies like QtQuick, which in turn gives the designer the ability to
create smooth, animated user interfaces.
Check the `debian/control` file to understand specific build and runtime dependencies, or use `cmake` to check for missing necessary components.
SDDM is extremely themeable. We put no restrictions on the user interface design,
it is completely up to the designer. We simply provide a few callbacks to the user interface
which can be used for authentication, suspend etc.
Core build dependencies:
To further ease theme creation we provide some premade components like a textbox,
a combox etc.
- [waylib](https://github.com/vioken/waylib): A Wayland compositor development library based on wlroots and QtQuick
- Qt >= 6.8.0
- wlroots = 0.19
- [treeland-protocols](https://github.com/linuxdeepin/treeland-protocols): Private Wayland protocols used by treeland
There are a few sample themes distributed with SDDM.
They can be used as a starting point for new themes.
Recommended runtime dependencies:
## SCREENSHOTS
- [ddm](https://github.com/linuxdeepin/ddm): A display manager optimized for multiple users
![sample screenshot](https://raw.github.com/ddm/ddm/master/src/greeter/theme/maui.jpg)
## Building
## VIDEOS
Treeland uses cmake for building. The WITH_SUBMODULE_WAYLIB option can force the use of the waylib code from the submodule. If you want to use the system-provided waylib, set this option to OFF.
* [Video background](https://www.youtube.com/watch?v=kKwz2FQcE3c)
* [Maui theme 1](https://www.youtube.com/watch?v=-0d1wkcU9DU)
* [Maui theme 2](https://www.youtube.com/watch?v=dJ28mrOeuNA)
Using the system-provided waylib:
## RESOURCES
```shell
$ git clone git@github.com:linuxdeepin/treeland.git
$ cd treeland
$ cmake -Bbuild -DWITH_SUBMODULE_WAYLIB=OFF
$ cmake --build build
* [Issue tracker](https://github.com/ddm/ddm/issues)
* [Wiki](https://github.com/ddm/ddm/wiki)
* [Mailing List](https://groups.google.com/group/ddm-devel)
* IRC channel `#ddm` on [chat.freenode.net](https://webchat.freenode.net?channels=ddm)
## INSTALLATION
Qt >= 5.15.0 is required to use SDDM.
SDDM runs the greeter as a system user named "ddm" whose home directory needs
to be set to `/var/lib/ddm`.
If pam and systemd are available, the greeter will go through logind
which will give it access to drm devices.
Distributions without pam and systemd will need to put the "ddm" user
into the "video" group, otherwise errors regarding GL and drm devices
might be experienced.
## VIRTUAL TERMINALS
SDDM is assumed to start at the tty specified by the cmake variable
SDDM_INITIAL_VT which is an integer and defaults to 1.
If SDDM_INITIAL_VT wasn't available, SDDM will use the next available one
instead.
You can override SDDM_INITIAL_VT if you want to have a different one if,
for example, you were planning on using tty1 for something else.
## LICENSE
Source code of SDDM is licensed under GNU GPL version 2 or later (at your choosing).
QML files are MIT licensed and images are CC BY 3.0.
## TROUBLESHOOTING
### NVIDIA Prime
Add this at the bottom of the Xsetup script:
```sh
if [ -e /sbin/prime-offload ]; then
echo running NVIDIA Prime setup /sbin/prime-offload, you will need to manually run /sbin/prime-switch to shut down
/sbin/prime-offload
fi
```
Using the waylib from the submodule:
### No User Icon
```shell
$ git clone git@github.com:linuxdeepin/treeland.git --recursive
$ cd treeland
$ cmake -Bbuild -DWITH_SUBMODULE_WAYLIB=ON
$ cmake --build build
SDDM reads user icon from either ~/.face.icon or FacesDir/username.face.icon
You need to make sure that SDDM user have permissions to read those files.
In case you don't want to allow other users to access your $HOME you can use
ACLs if your filesystem does support it.
```sh
setfacl -m u:ddm:x /home/username
setfacl -m u:ddm:r /home/username/.face.icon
```
## Packaging
### Custom DPI
A `debian` folder is provided to build the package under the *deepin* linux desktop distribution. To build the package, use the following command:
In order to set custom DPI for high resolution screens you should configure
Xorg yourself. An easy way is to pass an additional argument to Xorg.
```shell
$ sudo apt build-dep . # install build dependencies
$ dpkg-buildpackage -uc -us -nc -b # build binary package(s)
Edit ``/etc/ddm.conf``, go to the ``X11`` section and change ``ServerArguments`` like this:
```
ServerArguments=-nolisten tcp -dpi 192
```
## GitHub Actions / CI
to set DPI to 192.
This project uses GitHub Actions for continuous integration. The following workflows are configured:
- **qwlroots builds**: Triggered when `qwlroots/**` files are modified
- **waylib builds**: Triggered when `waylib/**` or `qwlroots/**` files are modified (since waylib depends on qwlroots)
- **treeland builds**: Main project builds
The waylib workflows are configured to also trigger when qwlroots code changes, ensuring that waylib builds remain compatible with qwlroots modifications.
## Getting Involved
- [Code contribution via GitHub](https://github.com/linuxdeepin/treeland/)
- [Submit bug or suggestions to GitHub Issues or GitHub Discussions](https://github.com/linuxdeepin/developer-center/issues/new/choose)
## License
treeland is licensed under Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only.
As an alternative you can edit Xorg configuration ``xorg.conf``, please refer to the
Xorg documentation.

View File

@ -1,67 +1 @@
# Treeland
treeland 是一个基于 wlroots 和 QtQuick 开发的 Wayland 合成器,旨在提供高效且灵活的图形界面支持。
## 依赖
查看 `debian/control` 文件来了解具体的构建与运行时依赖,或者使用 `cmake` 检查缺失的必要组件。
核心构建依赖:
- [waylib](https://github.com/vioken/waylib) 整合 wlroots 和 QtQuick 的 Wayland 合成器开发库
- Qt >= 6.8.0
- wlroots = 0.19
- [treeland-protocols](https://github.com/linuxdeepin/treeland-protocols) treeland 使用的私有 wayland 协议
推荐的运行时依赖:
- [ddm](https://github.com/linuxdeepin/ddm) 为多用户优化的登录管理器
## 构建
treeland 使用 cmake 进行构建,`WITH_SUBMODULE_WAYLIB` 选项可以强制使用子模块中的 `waylib` 代码,如果希望使用系统提供的 `waylib` 应该设置为 `OFF`
使用系统库提供的 `waylib`
```shell
$ git clone git@github.com:linuxdeepin/treeland.git
$ cd treeland
$ cmake -Bbuild -DWITH_SUBMODULE_WAYLIB=OFF
$ cmake --build build
```
使用子模块中的 `waylib`
```shell
$ git clone git@github.com:linuxdeepin/treeland.git --recursive
$ cd treeland
$ cmake -Bbuild -DWITH_SUBMODULE_WAYLIB=ON
$ cmake --build build
```
## 打包
*deepin* 桌面发行版进行此软件包的构建,我们还提供了一个 `debian` 目录。若要构建软件包,可参照下面的命令进行构建:
```shell
$ sudo apt build-dep . # 安装构建依赖
$ dpkg-buildpackage -uc -us -nc -b # 构建二进制软件包
```
## GitHub Actions / 持续集成
本项目使用 GitHub Actions 进行持续集成。配置了以下工作流:
- **qwlroots 构建**:当 `qwlroots/**` 文件被修改时触发
- **waylib 构建**:当 `waylib/**``qwlroots/**` 文件被修改时触发(因为 waylib 依赖于 qwlroots
- **treeland 构建**:主项目构建
waylib 工作流配置为在 qwlroots 代码变化时也会触发,确保 waylib 构建与 qwlroots 修改保持兼容。
## 参与贡献
- [通过 GitHub 发起代码贡献](https://github.com/linuxdeepin/treeland/)
- [通过 GitHub Issues 与 GitHub Discussions 汇报缺陷与反馈建议](https://github.com/linuxdeepin/developer-center/issues/new/choose)
## 许可协议
**Treeland** 使用 Apache-2.0, LGPL-3.0-only, GPL-2.0-only 或 GPL-3.0-only 许可协议进行发布。
TODO:

View File

@ -3,7 +3,7 @@ SPDX-PackageName = "treeland"
SPDX-PackageDownloadLocation = "https://github.com/linuxdeepin/treeland"
[[annotations]]
path = [".github/**", ".obs/**.yml", "garnix.yaml", ".tx/*"]
path = [".github/**", ".obs/**.yml", "garnix.yaml"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
@ -61,192 +61,3 @@ path = ["src/greeter/**.h", "src/greeter/**.cpp"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "GPL-2.0-only"
[[annotations]]
path = ["qwlroots/**"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "Apache-2.0"
# ===== WAYLIB REUSE Configuration =====
# CI and build files for waylib
[[annotations]]
path = ["waylib/.github/**", "waylib/.obs/**.yml", "waylib/renovate.json"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# Gitignore and git modules for waylib
[[annotations]]
path = ["waylib/.gitignore", "waylib/.gitmodules"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# Project files for waylib
[[annotations]]
path = ["waylib/**.cmake", "waylib/*CMakeLists.txt", "waylib/**.pc.in", "waylib/**cmake.in"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# README for waylib
[[annotations]]
path = ["waylib/README.md", "waylib/README.zh_CN.md"]
precedence = "aggregate"
SPDX-FileCopyrightText = "JiDe Zhang"
SPDX-License-Identifier = "CC-BY-4.0"
# Nix Develop files for waylib
[[annotations]]
path = ["waylib/**.nix", "waylib/.envrc", "waylib/flake.lock"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# Debian package for waylib
[[annotations]]
path = ["waylib/debian/**"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# C++ pch files for waylib
[[annotations]]
path = ["waylib/src/server/pch/pch.hxx"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# Core waylib files
[[annotations]]
path = [
"waylib/examples/tinywl/qml.qrc",
"waylib/tests/manual/cursor/cursor.qrc",
"waylib/src/server/kernel/WBackend",
"waylib/src/server/kernel/WCursor",
"waylib/src/server/kernel/WInputDevice",
"waylib/src/server/kernel/WInputEvent",
"waylib/src/server/kernel/WOutput",
"waylib/src/server/kernel/WSeat",
"waylib/src/server/kernel/WEvent",
"waylib/src/server/kernel/WServer",
"waylib/src/server/kernel/WServerInterface",
"waylib/src/server/kernel/WSurface",
"waylib/src/server/kernel/WSurfaceLayout",
"waylib/src/server/kernel/WTexture",
"waylib/src/server/kernel/WXdgShell",
"waylib/src/server/kernel/WXdgSurface",
"waylib/src/server/kernel/WLayerSurface",
"waylib/src/server/qtquick/WQuickRenderControl",
"waylib/src/server/qtquick/WSurfaceItem",
"waylib/src/server/utils/WSignalConnector",
"waylib/src/server/utils/WThreadUtils",
"waylib/src/server/utils/WCursorImage",
"waylib/src/server/utils/WWrapPointer",
"waylib/tests/main.cpp",
"waylib/tests/test.h"
]
precedence = "aggregate"
SPDX-FileCopyrightText = "JiDe Zhang"
SPDX-License-Identifier = "Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"
# Waylib protocol files
[[annotations]]
path = [
"waylib/src/server/protocols/WCursorShapeManagerV1",
"waylib/src/server/protocols/WForeignToplevel",
"waylib/src/server/protocols/WInputMethodHelper",
"waylib/src/server/protocols/WLayerSurface",
"waylib/src/server/protocols/WOutputManagerV1",
"waylib/src/server/protocols/WXdgOutput",
"waylib/src/server/protocols/WXdgShell",
"waylib/src/server/protocols/WXdgSurface",
"waylib/src/server/protocols/WLayerShell",
"waylib/src/server/protocols/WInputPopupSurface",
"waylib/src/server/protocols/WXWayland",
"waylib/src/server/protocols/WXWaylandSurface",
"waylib/src/server/protocols/WXdgDecorationManager",
"waylib/src/server/protocols/WSessionLock",
"waylib/src/server/protocols/WSessionLockManager",
"waylib/src/server/protocols/WSessionLockSurface"
]
precedence = "aggregate"
SPDX-FileCopyrightText = "UnionTech Software Technology Co., Ltd."
SPDX-License-Identifier = "Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"
# Misc files for waylib
[[annotations]]
path = [
"waylib/tests/manual/cursor/res/HandCursor.png",
"waylib/examples/tinywl/res/xx.jpg"
]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# Protocol files with HPND license for waylib
[[annotations]]
path = ["waylib/src/server/protocols/private/text-input-unstable-v2.xml"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "HPND"
# ===== QWLROOTS REUSE Configuration =====
# CI for qwlroots
[[annotations]]
path = ["qwlroots/.github/**", "qwlroots/.obs/**.yml", "qwlroots/garnix.yaml"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# Project files for qwlroots
[[annotations]]
path = [
"qwlroots/**.cmake",
"qwlroots/*CMakeLists.txt",
"qwlroots/**.pc.in",
"qwlroots/**cmake.in",
"qwlroots/.gitignore",
"qwlroots/.cursorindexingignore",
"qwlroots/.cursor/rules/**.mdc",
"qwlroots/.gitmodules"
]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# Simple header files for qwlroots
[[annotations]]
path = [
"qwlroots/**/qwkeyboard.h",
"qwlroots/**/qwpointer.h",
"qwlroots/**/qwswitch.h",
"qwlroots/**/qwtablet.h",
"qwlroots/**/qwtabletpad.h",
"qwlroots/**/qwtouch.h"
]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# README and documentation for qwlroots
[[annotations]]
path = ["qwlroots/README.md", "qwlroots/README.zh_CN.md", "qwlroots/doc/ai/**.md"]
precedence = "aggregate"
SPDX-FileCopyrightText = "JiDe Zhang"
SPDX-License-Identifier = "CC-BY-4.0"
# Nix Develop files for qwlroots
[[annotations]]
path = ["qwlroots/**.nix", "qwlroots/.envrc", "qwlroots/flake.lock"]
precedence = "aggregate"
SPDX-FileCopyrightText = "None"
SPDX-License-Identifier = "CC0-1.0"
# Debian package for qwlroots
[[annotations]]
path = ["qwlroots/debian/**"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2023 rewine <luhongxu@outlook.com>"
SPDX-License-Identifier = "Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"

View File

@ -1,60 +0,0 @@
include(CMakeParseArguments)
function(impl_treeland)
set(one_value_args NAME)
set(multi_value_args SOURCE INCLUDE LINK)
cmake_parse_arguments(
PARSE_ARG_PREFIX
""
"${one_value_args}"
"${multi_value_args}"
${ARGN}
)
if(NOT PARSE_ARG_PREFIX_NAME)
message(FATAL_ERROR "NAME is a required argument!")
endif()
add_library(${PARSE_ARG_PREFIX_NAME} INTERFACE)
target_sources(${PARSE_ARG_PREFIX_NAME}
INTERFACE
${PARSE_ARG_PREFIX_SOURCE}
)
target_include_directories(${PARSE_ARG_PREFIX_NAME}
INTERFACE
${PARSE_ARG_PREFIX_INCLUDE}
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
)
target_link_libraries(${PARSE_ARG_PREFIX_NAME}
INTERFACE
${PARSE_ARG_PREFIX_LINK}
# TODO: remove this
Dtk6::Core
Dtk6::Declarative
Dtk6::SystemSettings
Waylib::WaylibServer
Qt6::Quick
Qt6::QuickControls2
Qt6::QuickPrivate
Qt6::DBus
Qt6::Concurrent
PkgConfig::PIXMAN
PkgConfig::WAYLAND
PkgConfig::LIBINPUT
# TODO: end remove
)
target_link_libraries(libtreeland
PRIVATE
${PARSE_ARG_PREFIX_NAME}
)
endfunction()

View File

@ -1,62 +0,0 @@
# TranslationUtils.cmake
# Provides common functions for handling translation files
function(setup_translations TARGET_NAME TRANSLATION_PREFIX)
# Automatically discover all translation files
file(GLOB TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/translations/${TRANSLATION_PREFIX}.*.ts")
# Filter out non-translation files (if any)
list(FILTER TS_FILES INCLUDE REGEX ".*\\.ts$")
# Set translation files variable
set(TRANSLATED_FILES)
# Add lupdate target
qt_add_lupdate(
SOURCE_TARGETS ${TARGET_NAME}
TS_FILES ${TS_FILES}
NO_GLOBAL_TARGET
)
# Add lrelease target
qt_add_lrelease(
TS_FILES ${TS_FILES}
QM_FILES_OUTPUT_VARIABLE TRANSLATED_FILES
)
# Install translation files
install(FILES ${TRANSLATED_FILES} DESTINATION ${TREELAND_COMPONENTS_TRANSLATION_DIR})
# Set TRANSLATED_FILES variable to parent scope
set(TRANSLATED_FILES ${TRANSLATED_FILES} PARENT_SCOPE)
endfunction()
function(setup_main_translations TARGET_NAME)
# Automatically discover all main translation files
file(GLOB TS_FILES "${CMAKE_SOURCE_DIR}/translations/treeland.*.ts")
# Filter out non-translation files (if any)
list(FILTER TS_FILES INCLUDE REGEX ".*\\.ts$")
# Set translation files variable
set(TRANSLATED_FILES)
# Add lupdate target
qt_add_lupdate(
SOURCE_TARGETS ${TARGET_NAME}
TS_FILES ${TS_FILES}
NO_GLOBAL_TARGET
)
# Add lrelease target
qt_add_lrelease(
TS_FILES ${TS_FILES}
QM_FILES_OUTPUT_VARIABLE TRANSLATED_FILES
)
# Install translation files
install(FILES ${TRANSLATED_FILES} DESTINATION ${TREELAND_COMPONENTS_TRANSLATION_DIR})
# Set TRANSLATED_FILES variable to parent scope
set(TRANSLATED_FILES ${TRANSLATED_FILES} PARENT_SCOPE)
endfunction()

333
debian/changelog vendored
View File

@ -1,336 +1,3 @@
treeland (0.7.6) unstable; urgency=medium
* refactor: implement atomic multi-output configuration
* fix: occasional crash during recording toplevel
* fix: use safeConnect for aboutToBeInvalidated
* i18n: Updates for project TreeLand (#601)
* refactor: Convert Session to shared_ptr and simplify session
lifecycle
* chore: Remove unused code & Add document
* feat: Manage per-user Wayland/XWayland sessions via Helper::Session
* feat: Add per-user XWayland session management
* chore: add ASAN environment variables
* feat: Expose XWayland surface process ID
* chore: change Debian build environment to unstable
* refactor: remove branch filter for workflow triggers
* fix: fix build when treeland examples are enabled
* fix: fix build failure on Arch Linux
* fix: Disable minimize / maximize animation for window that doesn't
belongs to current user
* fix: fix private module inclusion on lower version of Qt
* fix: compile errors on Arch for forward declared class
* fix: include Qt private modules for Qt 6.11
* feat: add real-time FPS display
* feat: support start sessions other than treeland
* feat: implement ext-session-lock-v1 support
* feat(waylib): implement ext-session-lock-v1 protocol support
* fix(waylib): Add missing override specifier in wlayersurface
* fix(qwlroots): allow server side destruction of qw_session_lock_v1
* fix: Delete useless display text in copy mode
* fix: enhance output validation in restore copy mode
* fix: use separate TreelandConfig for each user
* fix: Ensure proper object destruction before app exit
* fix: improve resource management for RenderControl
* fix: fix heap-use-after-free on exit
-- rewine <luhongxu@uniontech.com> Thu, 30 Oct 2025 14:04:56 +0800
treeland (0.7.3) unstable; urgency=medium
* fix: fix WorkspaceSelectionList animation's highlight border size
* fix: fix MultitaskView display problem
* refactor: reduce cursor-related log verbosity
* fix: fix MultitaskView display problem caused by refactoring
TreelandConfig
* Updates for project TreeLand (#563)
-- rewine <luhongxu@uniontech.com> Tue, 23 Sep 2025 17:24:35 +0800
treeland (0.7.2) unstable; urgency=medium
* fix: crash on startup due to uninitialized m_config pointer
-- rewine <luhongxu@uniontech.com> Fri, 19 Sep 2025 10:06:51 +0800
treeland (0.7.1) unstable; urgency=medium
* fix: Fix socket blocking issue in Wayland server connection handling
* fix: correct window title visibility condition
* fix: Fix client crash when created via security context
* feat: add security-context support
* fix: Separate DConfig object creation to another thread to avoid
blocking
* fix: move DBus call to separate thread to avoid blocking
* fix: fixing some trivial memory management bugs.
* feat(core): Add support for XDG toplevel surface and XDG shell in
RootSurfaceContainer
* fix: correct refresh rate on multi-monitor
* fix: redraw when frame callback list updates
-- rewine <luhongxu@uniontech.com> Thu, 18 Sep 2025 11:46:00 +0800
treeland (0.7.0) unstable; urgency=medium
* fix: fix treeland get stuck in lockscreen after crash recovery
* fix: occasional crash during stop preview item handling
* refactor: improve code robustness
* fix: occasional crash when closing x window
* fix: resolve brief black screen during standby
* chore: remove dde portal screen cast configuration
* fix: correct log category and add null check for surface activation
* fix: resolve window resize crash during image capture
* fix: fix wrong display render issue when switching VT too quickly
* Totally disable lockscreen animation when switching TTY to prevent
stuck for switching too quickly
* feat: Support TTY switching with DDM
* Updates for project TreeLand (#515)
* feat(waylib): add WBufferDumper utility for dumping buffer contents
to image files
* refactor: use unified CI build preset with Werror
* build: enable -Werror compiler flag
* fix: prevent crash during preview item handling (#512)
* fix: prevent cursor flicker during screen recording
* docs: add comprehensive logging guidelines and update module logging
* feat: add centralized logging system and standardize log usage
* feat: ssd title bar displays the window title information
* fix: maximize/restore icon in the SSD title bar displays incorrectly
* fix: resolve multiple compiler warnings
* fix(waylib): prevent duplicate signal connections using
Qt::UniqueConnection
* fix(waylib): prevent crash by safely managing textureChanged
connection
* fix: use exec to replace process and avoid duplicate logs in
treeland.sh
* fix(waylib): Occasional crash when moving the cursor
-- rewine <luhongxu@uniontech.com> Fri, 29 Aug 2025 10:23:45 +0800
treeland (0.6.2) unstable; urgency=medium
* fix: resolve library versioning and installation path issues
-- rewine <luhongxu@uniontech.com> Mon, 04 Aug 2025 17:42:40 +0800
treeland (0.6.1) unstable; urgency=medium
* fix: improve D-Bus connection handling and QML hover visibility
* feat: CLI option: switch from --disable-debug-view to --enable-debug-
view
* fix(waylib): Specify required rendering flags in
WSGRenderFootprintNode
-- rewine <luhongxu@uniontech.com> Fri, 01 Aug 2025 13:33:07 +0800
treeland (0.6.0) unstable; urgency=medium
* fix: improve image capture error handling and code structure
* feat: add foreign toplevel image capture support
* feat: add image capture source support
* fix: remove unused quit full button and add helper activation
* fix: prevent title bar and window buttons from stealing focus
* feat: add wl_drm support
* feat: create ext-data-control manager
* fix: Handle VT switching keys (#469)
* feat: add Nix flake support for project configuration
* fix: prevent workspace moveSurfaceTo crash on null wrapper
* fix: remove redundant submodule options and configs
* chore: update nix dependencies and clean up configurations
* fix: Scaling animation not shown while return from shutdown page
* chore: Force Ninja build during deb packaging
* fix: add timeout to protocol tests
* feat: Upload build artifacts as zip archives
* chore: fix CI and enable independent builds
* refactor: merge qwlroots and waylib source code into treeland
* chore: Use treeland-specific seatd service
* feat: implement ext-foreign-toplevel-list
* i18n: Updates for project TreeLand (#440)
* chore: remove polkit rules for login1
* feat: add support for alpha modifier protocol
* fix: cannot export dbus services
* Revert "fix: should not maximize when client set maxsize"
* Updates for project TreeLand (#431)
* fix: Treeland does not exit when logging out of session
* fix: cannot use treeland user session mode
* fix: add [[maybe_unused]] attribute to unused parameters
* chore: improvement fixes the translation configuration
* feat: add popup surface container for handling popup windows
* chore: configure translation files and update Chinese translations
* chore: configure transifex translation files
* feat: adapt to wlroots-0.19
* refactor: remove jemalloc dependency
-- rewine <luhongxu@uniontech.com> Thu, 31 Jul 2025 20:40:50 +0800
treeland (0.5.21) unstable; urgency=medium
* fix: inputted password and capsIndicator button are covered
-- rewine <luhongxu@deepin.org> Thu, 17 Apr 2025 15:17:48 +0800
treeland (0.5.20) unstable; urgency=medium
* fix: activeColor not saved to dconfig
* fix: send error output enter for layer shell
* chore: input popup should not use radius
-- rewine <luhongxu@deepin.org> Mon, 10 Mar 2025 16:20:35 +0800
treeland (0.5.19) unstable; urgency=medium
* fix: can't set output's postion
* fix: layer shell's popup not enter popup container
-- rewine <luhongxu@deepin.org> Sat, 15 Feb 2025 15:30:10 +0800
treeland (0.5.18) unstable; urgency=medium
* fix: the tooltip text may disappear unexpectedly
* fix: can't start on VirtualBox
* feat: cache outputs settings
-- rewine <luhongxu@deepin.org> Fri, 14 Feb 2025 10:31:38 +0800
treeland (0.5.17) unstable; urgency=medium
* fix: nix ci for build
* Fix missing treeland's translations
-- Groveer <guoyao@uniontech.com> Wed, 15 Jan 2025 11:02:18 +0800
treeland (0.5.16) unstable; urgency=medium
* fix: crashed at accessing surface
* Fix crash at QStyleHints
-- zhangkun <zhangkun2@uniontech.com> Tue, 14 Jan 2025 16:16:43 +0800
treeland (0.5.15) unstable; urgency=medium
* chore: update default window corner size
-- zhangkun <zhangkun2@uniontech.com> Tue, 14 Jan 2025 11:45:30 +0800
treeland (0.5.14) unstable; urgency=medium
* Fix crash at PersonalizationAttached::noTitlebar
* Add a background color for DockPreview
-- JiDe Zhang <zhangjide@uniontech.com> Mon, 13 Jan 2025 18:13:21 +0800
treeland (0.5.13) unstable; urgency=medium
* feat: add ctrl-alt-del shortcut key
* Add TREELAND_SESSION_ENVIRONMENTS env
* fix: popup of screen recorder is below it's parent
* Fix typo
* Ignore window rounded radius when maximized
-- JiDe Zhang <zhangjide@uniontech.com> Mon, 13 Jan 2025 11:02:32 +0800
treeland (0.5.12) unstable; urgency=medium
* Fix maybe freeze when display DockPreview
* feat: update default values
* fix: adjust UI for greeter
-- Groveer <guoyao@uniontech.com> Wed, 08 Jan 2025 11:22:31 +0800
treeland (0.5.11) unstable; urgency=medium
* bump version to 0.5.11
-- Groveer <guoyao@uniontech.com> Wed, 25 Dec 2024 18:47:45 +0800
treeland (0.5.10) unstable; urgency=medium
* bump version to 0.5.10
-- Groveer <guoyao@uniontech.com> Fri, 20 Dec 2024 16:04:58 +0800
treeland (0.5.9) unstable; urgency=medium
* bump version to 0.5.9
-- Groveer <guoyao@uniontech.com> Tue, 17 Dec 2024 21:04:15 +0800
treeland (0.5.8) unstable; urgency=medium
* bump version to 0.5.8
-- Groveer <guoyao@uniontech.com> Fri, 13 Dec 2024 14:14:01 +0800
treeland (0.5.7) unstable; urgency=medium
* bump version to 0.5.7
-- Groveer <guoyao@uniontech.com> Tue, 10 Dec 2024 18:29:02 +0800
treeland (0.5.6) unstable; urgency=medium
* bump version to 0.5.6
-- rewine <luhongxu@deepin.org> Fri, 06 Dec 2024 15:05:05 +0800
treeland (0.5.5) unstable; urgency=medium
* bump version to 0.5.5
-- Groveer <guoyao@uniontech.com> Thu, 05 Dec 2024 21:22:32 +0800
treeland (0.5.4) unstable; urgency=medium
* bump version to 0.5.4
-- Groveer <guoyao@uniontech.com> Sat, 30 Nov 2024 15:52:51 +0800
treeland (0.5.3) unstable; urgency=medium
* bump version to 0.5.3
-- Groveer <guoyao@uniontech.com> Fri, 29 Nov 2024 15:58:26 +0800
treeland (0.5.2) unstable; urgency=medium
* bump version to 0.5.2
-- Groveer <guoyao@uniontech.com> Tue, 26 Nov 2024 15:01:56 +0800
treeland (0.5.1) unstable; urgency=medium
* bump version to 0.5.1
-- Groveer <guoyao@uniontech.com> Fri, 22 Nov 2024 18:10:04 +0800
treeland (0.5.0) unstable; urgency=medium
* bump version to 0.5.0
-- Groveer <guoyao@uniontech.com> Thu, 21 Nov 2024 17:02:20 +0800
treeland (0.4.4) unstable; urgency=medium
* bump version to 0.4.4
-- Groveer <guoyao@uniontech.com> Fri, 15 Nov 2024 14:15:57 +0800
treeland (0.4.3) unstable; urgency=medium
* bump version to 0.4.3
-- Groveer <guoyao@uniontech.com> Mon, 11 Nov 2024 19:10:14 +0800
treeland (0.4.1) unstable; urgency=medium
* update appearance protocol
-- Dingyuan Zhang <zhangdingyuan@uniontech.com> Thu, 01 Nov 2024 11:20:00 +0800
treeland (0.4) unstable; urgency=medium
* update workspace
-- Dingyuan Zhang <zhangdingyuan@uniontech.com> Thu, 01 Nov 2024 11:20:00 +0800
treeland (0.3) unstable; urgency=medium
* support windows animation

33
debian/control vendored
View File

@ -3,38 +3,28 @@ Priority: optional
Maintainer: rewine <luhongxu@deepin.org>
Build-Depends: cmake (>= 3.4~),
debhelper-compat (= 13),
ninja-build,
extra-cmake-modules (>= 1.4.0~),
libddm-dev,
libdtk6core-bin,
libdtk6core-dev,
libdtk6declarative-dev,
libdtk6gui-dev,
libdtk6systemsettings-dev,
libdtkcommon-dev,
libsystemd-dev [linux-any],
systemd,
libwlroots-0.19-dev,
libpixman-1-dev,
libxcb-ewmh-dev,
libdrm-dev,
libwaylib-dev,
libwlroots-dev (>=0.17.0),
pkg-config,
qml6-module-qtquick-templates,
qt6-base-dev (>= 6.6.1~),
qt6-base-private-dev (>= 6.6.1~),
qt6-base-dev-tools (>= 6.6.0),
qt6-declarative-dev (>= 6.6.1~),
qt6-declarative-private-dev (>= 6.6.0),
qt6-shadertools-dev,
qt6-tools-dev,
qt6-tools-dev-tools (>= 6.6.1~),
qt6-wayland,
qt6-wayland-dev,
qt6-wayland-private-dev,
wayland-protocols,
qwlroots,
wlr-protocols,
treeland-protocols,
libpam0g-dev,
Standards-Version: 4.6.0
Section: dde
Homepage: https://github.com/linuxdeepin/treeland.git
@ -51,18 +41,6 @@ Depends: qml6-module-qtquick-layouts,
treeland-data (= ${source:Version}),
xwayland,
${shlibs:Depends},
Conflicts: libwaylib, qwlroots
Replaces: libwaylib, qwlroots
Recommends: ddm,
Description: a Wayland compositor based on wlroots and QML, designed with an attractive and elegant appearance.
Package: treeland-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: ${misc:Depends}, treeland( =${source:Version}),
Conflicts: libwaylib-dev, qwlroots
Replaces: libwaylib-dev, qwlroots
Description: a Wayland compositor based on wlroots and QML, designed with an attractive and elegant appearance.
Package: treeland-examples
@ -78,9 +56,8 @@ Architecture: all
Depends: ${misc:Depends},
Description: data files of treeland.
Package: treeland-wayland-session
Package: treeland-protocols
Section: dde
Architecture: all
Depends: ${misc:Depends},
treeland (= ${source:Version}),
Description: treeland user session files of treeland.
Description: wayland protocols of treeland.

6
debian/rules vendored
View File

@ -8,12 +8,14 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# see ENVIRONMENT in dpkg-buildflags(1)
# package maintainers to append CFLAGS
# export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# package maintainers to append LDFLAGS
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
TREELAND_CMAKE_ARGS = -DBUILD_TEST_CLIENTS=on
%:
dh $@
override_dh_auto_configure:
dh_auto_configure -- --preset deb
dh_auto_configure -- ${TREELAND_CMAKE_ARGS}

View File

@ -1,3 +1,4 @@
usr/share/dsg/configs/*
usr/share/treeland/shortcuts/*
usr/share/wayland-sessions/treeland.desktop
usr/share/wayland-sessions/*
etc/xdg-desktop-portal/dde-portals.conf

View File

@ -1,5 +0,0 @@
usr/include/*
usr/lib/*/cmake/*
usr/lib/*/pkgconfig/*
usr/lib/*/lib*.so
usr/lib/*/lib*.a

3
debian/treeland-protocols.install vendored Normal file
View File

@ -0,0 +1,3 @@
usr/share/treeland-protocols/*
usr/share/cmake/TreeLandProtocols/*
usr/share/pkgconfig/treeland-protocols.pc

View File

@ -1,2 +0,0 @@
usr/share/wayland-sessions/treeland-user.desktop
usr/bin/treeland-user-wrapper

View File

@ -1,10 +1,5 @@
usr/bin/treeland
usr/bin/treeland.sh
usr/lib/systemd/user/*
usr/lib/systemd/system/*
usr/libexec/*
usr/share/*/translations/*
usr/share/dbus-1/system.d/*
usr/lib/*/lib*.so.*
usr/lib/*/treeland/plugins/lib*.so

View File

@ -1,27 +0,0 @@
{
pkgs ? import <nixpkgs> { },
nix-filter,
ddm,
treeland-protocols,
}:
rec {
qwlroots = pkgs.qt6Packages.callPackage ./qwlroots/nix {
inherit nix-filter;
wlroots = pkgs.wlroots_0_19;
};
waylib = pkgs.qt6Packages.callPackage ./waylib/nix {
inherit nix-filter qwlroots;
makeTest = import (pkgs.path + "/nixos/tests/make-test-python.nix");
};
treeland = pkgs.qt6Packages.callPackage ./nix {
inherit
nix-filter
ddm
treeland-protocols
qwlroots
waylib
;
};
}

View File

@ -1,177 +0,0 @@
# Logging Guidelines for Treeland Project
This document provides guidelines for logging in the Treeland project, covering both treeland and waylib modules.
## Overview
The Treeland project uses Qt's logging system with customized categories. There are two different approaches for treeland and waylib modules:
- **treeland**: Uses centralized logging categories defined in `treelandlogging.h/.cpp`
- **waylib**: Uses local logging category definitions in each file
## Logging Categories
### Treeland Module Categories
All logging categories for the treeland module are centrally defined in `src/common/treelandlogging.h`:
```cpp
// Core functionality
Q_DECLARE_LOGGING_CATEGORY(treelandCore)
// Input device handling
Q_DECLARE_LOGGING_CATEGORY(treelandInput)
// Output/display management
Q_DECLARE_LOGGING_CATEGORY(treelandOutput)
// Plugin system
Q_DECLARE_LOGGING_CATEGORY(treelandPlugin)
// And more...
```
### Waylib Module Categories
Waylib modules define their categories locally in each file. The category naming follows this pattern:
`waylib.<module>.<component>[.<subcomponent>]`
Example from wcursor.cpp:
```cpp
// Cursor management and movement
Q_LOGGING_CATEGORY(waylibCursor, "waylib.server.cursor", QtInfoMsg)
// Cursor input events
Q_LOGGING_CATEGORY(waylibCursorInput, "waylib.server.cursor.input", QtDebugMsg)
// Cursor gesture events
Q_LOGGING_CATEGORY(waylibCursorGesture, "waylib.server.cursor.gesture", QtDebugMsg)
```
## Log Levels
Use appropriate log levels based on the message importance:
- **Debug (qCDebug)**: Detailed information for debugging
- **Info (qCInfo)**: General operational information
- **Warning (qCWarning)**: Potentially harmful situations
- **Critical (qCCritical)**: Critical errors that need immediate attention
Example:
```cpp
qCDebug(waylibCursor) << "Processing cursor motion at" << position;
qCWarning(waylibCursorInput) << "Invalid button code:" << code;
qCCritical(treelandCore) << "Failed to initialize core component";
```
## Best Practices
1. **Clear and Contextual Messages**
- Include relevant context in log messages
```cpp
// Good
qCDebug(waylibCursor) << "Cursor moved from" << oldPos << "to" << newPos;
// Bad
qCDebug(waylibCursor) << "Cursor moved";
```
2. **Appropriate Log Levels**
- Debug: Development and troubleshooting
- Info: Normal operations
- Warning: Unexpected but recoverable
- Critical: Serious errors
3. **Category Organization**
- Use specific categories for better filtering
```cpp
// Instead of
qCDebug(waylibCursor) << "Touch event received";
// Use
qCDebug(waylibCursorTouch) << "Touch event received";
```
4. **State Changes**
- Log important state changes with before/after values
```cpp
qCDebug(waylibCursor) << "Visibility changed from" << oldVisible << "to" << newVisible;
```
5. **Error Handling**
- Include error details and potential impact
```cpp
qCWarning(waylibCursor) << "Failed to attach device" << device->name()
<< "- not a pointing device";
```
## Implementation Examples
### Treeland Module
```cpp
#include "treelandlogging.h"
void ExampleClass::processEvent()
{
qCDebug(treelandCore) << "Processing event:" << eventType;
if (error) {
qCWarning(treelandCore) << "Event processing failed:" << errorDetails;
}
}
```
### Waylib Module
```cpp
// Local category definition
Q_LOGGING_CATEGORY(waylibExample, "waylib.module.example", QtInfoMsg)
void ExampleClass::processEvent()
{
qCDebug(waylibExample) << "Processing event:" << eventType;
if (error) {
qCWarning(waylibExample) << "Event processing failed:" << errorDetails;
}
}
```
## Debugging Tips
1. **Enable/Disable Categories**
```bash
export QT_LOGGING_RULES="waylib.server.cursor.debug=true"
export QT_LOGGING_RULES="waylib.*.debug=false"
```
2. **Log to File**
```bash
export QT_LOGGING_TO_FILE=1
export QT_LOGGING_OUTPUT=/path/to/logfile.txt
```
## Common Mistakes to Avoid
1. **Don't expose sensitive information**
```cpp
// Bad
qCDebug(treelandCore) << "User password:" << password;
```
2. **Don't mix categories inappropriately**
```cpp
// Bad
qCDebug(treelandInput) << "Cursor position changed"; // Should use cursor category
```
3. **Don't overuse Critical level**
```cpp
// Bad
qCCritical(waylibCursor) << "Minor position adjustment failed";
```
## Contributing
When contributing to the project:
1. Follow the established category naming patterns
2. Use appropriate log levels
3. Provide clear and contextual messages
4. Add new categories through proper channels (centralized for treeland, local for waylib)
For questions about logging, please refer to this guide or contact the maintainers.

View File

@ -1,177 +0,0 @@
# Treeland 项目日志指南
本文档提供了 Treeland 项目的日志指南,涵盖了 treeland 和 waylib 模块。
## 概述
Treeland 项目使用 Qt 的日志系统并自定义了日志类别。treeland 和 waylib 模块采用了两种不同的方式:
- **treeland**:使用在 `treelandlogging.h/.cpp` 中集中定义的日志类别
- **waylib**:在各个文件中本地定义日志类别
## 日志类别
### Treeland 模块类别
所有 treeland 模块的日志类别都集中定义在 `src/common/treelandlogging.h` 中:
```cpp
// 核心功能
Q_DECLARE_LOGGING_CATEGORY(treelandCore)
// 输入设备处理
Q_DECLARE_LOGGING_CATEGORY(treelandInput)
// 输出/显示管理
Q_DECLARE_LOGGING_CATEGORY(treelandOutput)
// 插件系统
Q_DECLARE_LOGGING_CATEGORY(treelandPlugin)
// 更多...
```
### Waylib 模块类别
Waylib 模块在各自的文件中定义类别。类别命名遵循以下模式:
`waylib.<模块>.<组件>[.<子组件>]`
来自 wcursor.cpp 的示例:
```cpp
// 光标管理和移动
Q_LOGGING_CATEGORY(waylibCursor, "waylib.server.cursor", QtInfoMsg)
// 光标输入事件
Q_LOGGING_CATEGORY(waylibCursorInput, "waylib.server.cursor.input", QtDebugMsg)
// 光标手势事件
Q_LOGGING_CATEGORY(waylibCursorGesture, "waylib.server.cursor.gesture", QtDebugMsg)
```
## 日志级别
根据消息的重要性使用适当的日志级别:
- **Debug (qCDebug)**:调试信息,用于开发调试
- **Info (qCInfo)**:一般操作信息
- **Warning (qCWarning)**:潜在的有害情况
- **Critical (qCCritical)**:需要立即关注的严重错误
示例:
```cpp
qCDebug(waylibCursor) << "正在处理光标移动,位置:" << position;
qCWarning(waylibCursorInput) << "无效的按钮代码:" << code;
qCCritical(treelandCore) << "核心组件初始化失败";
```
## 最佳实践
1. **清晰和上下文相关的消息**
- 在日志消息中包含相关上下文
```cpp
// 好的做法
qCDebug(waylibCursor) << "光标从" << oldPos << "移动到" << newPos;
// 不好的做法
qCDebug(waylibCursor) << "光标移动";
```
2. **适当的日志级别**
- Debug开发和故障排除
- Info正常操作
- Warning意外但可恢复的情况
- Critical严重错误
3. **类别组织**
- 使用特定类别以便更好地过滤
```cpp
// 不要这样
qCDebug(waylibCursor) << "收到触摸事件";
// 应该这样
qCDebug(waylibCursorTouch) << "收到触摸事件";
```
4. **状态变化**
- 记录重要的状态变化,包含前后的值
```cpp
qCDebug(waylibCursor) << "可见性从" << oldVisible << "变更为" << newVisible;
```
5. **错误处理**
- 包含错误详情和潜在影响
```cpp
qCWarning(waylibCursor) << "设备" << device->name()
<< "附加失败 - 不是指针设备";
```
## 实现示例
### Treeland 模块
```cpp
#include "treelandlogging.h"
void ExampleClass::processEvent()
{
qCDebug(treelandCore) << "正在处理事件:" << eventType;
if (error) {
qCWarning(treelandCore) << "事件处理失败:" << errorDetails;
}
}
```
### Waylib 模块
```cpp
// 本地类别定义
Q_LOGGING_CATEGORY(waylibExample, "waylib.module.example", QtInfoMsg)
void ExampleClass::processEvent()
{
qCDebug(waylibExample) << "正在处理事件:" << eventType;
if (error) {
qCWarning(waylibExample) << "事件处理失败:" << errorDetails;
}
}
```
## 调试技巧
1. **启用/禁用类别**
```bash
export QT_LOGGING_RULES="waylib.server.cursor.debug=true"
export QT_LOGGING_RULES="waylib.*.debug=false"
```
2. **日志输出到文件**
```bash
export QT_LOGGING_TO_FILE=1
export QT_LOGGING_OUTPUT=/path/to/logfile.txt
```
## 常见错误避免
1. **不要暴露敏感信息**
```cpp
// 错误
qCDebug(treelandCore) << "用户密码:" << password;
```
2. **不要混用类别**
```cpp
// 错误
qCDebug(treelandInput) << "光标位置改变"; // 应该使用光标类别
```
3. **不要过度使用 Critical 级别**
```cpp
// 错误
qCCritical(waylibCursor) << "轻微的位置调整失败";
```
## 贡献指南
在为项目贡献代码时:
1. 遵循既定的类别命名模式
2. 使用适当的日志级别
3. 提供清晰和上下文相关的消息
4. 通过正确的方式添加新类别treeland 集中定义waylib 本地定义)
如有关于日志的问题,请参考本指南或联系维护者。

View File

@ -1,19 +0,0 @@
set(MODULE_PATH ${PROJECT_SOURCE_DIR}/src/modules)
add_subdirectory(test_window_bg)
add_subdirectory(test_wallpaper_color)
add_subdirectory(test_show_desktop)
add_subdirectory(test_window_cursor)
add_subdirectory(test_xdgport_wallpaper)
add_subdirectory(test_virtual_output)
add_subdirectory(test_pinch_handler)
add_subdirectory(test_hide_window)
add_subdirectory(test_data_control_manager)
add_subdirectory(test_window_overlapped)
add_subdirectory(test_capture)
add_subdirectory(test_window_appearance)
add_subdirectory(test_super_overlay_surface)
add_subdirectory(test_monitor_active_event)
add_subdirectory(test_primary_output)
add_subdirectory(test_multitaskview)
add_subdirectory(test_set_treeland_wallpaper)

View File

@ -1,46 +0,0 @@
find_package(PkgConfig REQUIRED)
find_package(Qt6 REQUIRED COMPONENTS Core Gui WaylandClient Quick)
find_package(TreelandProtocols REQUIRED)
pkg_check_modules(EGL REQUIRED IMPORTED_TARGET egl gl)
qt_add_executable(test-capture
main.cpp
)
qt_add_qml_module(test-capture
URI capture
VERSION 2.0
SOURCES
capture.h
capture.cpp
subwindow.h
subwindow.cpp
player.h
player.cpp
QML_FILES
Main.qml
)
qt_add_resources(test-capture "test_capture_assets"
PREFIX "/"
BASE ${CMAKE_CURRENT_LIST_DIR}/images
FILES
${CMAKE_CURRENT_LIST_DIR}/images/watermark.png
)
qt6_generate_wayland_protocol_client_sources(test-capture
FILES
${TREELAND_PROTOCOLS_DATA_DIR}/treeland-capture-unstable-v1.xml
)
target_link_libraries(test-capture
PRIVATE
Qt6::Core
Qt6::Gui
Qt6::WaylandClient
Qt6::WaylandClientPrivate
Qt6::Quick
Qt6::QuickPrivate
Qt6::QuickControls2
PkgConfig::EGL
)
install(TARGETS test-capture RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

View File

@ -1,80 +0,0 @@
// Copyright (C) 2024 Dingyuan Zhang <lxz@mkacg.com>.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
import QtQuick.Controls
import capture
Window {
id: canvas
width: 600
height: 400
visible: !TreelandCaptureManager.recordStarted
color: "transparent"
flags: regionReady ? 0 : Qt.WindowTransparentForInput
property rect captureRegion: TreelandCaptureManager.context?.captureRegion ?? Qt.rect(0, 0, 0, 0)
property bool regionReady: captureRegion.width !== 0 && captureRegion.height !== 0
Image {
id: watermark
visible: false
source: "qrc:/watermark.png"
sourceSize: Qt.size(100, 100)
fillMode: Image.Tile
x: captureRegion.x
y: captureRegion.y
width: captureRegion.width
height: captureRegion.height
}
SubWindow {
id: toolBar
parent: canvas
visible: regionReady
x: captureRegion.x
y: Math.min(captureRegion.bottom, canvas.height - 2 * height)
width: row.width
height: row.height
color: "transparent"
Row {
id: row
Button {
width: 100
height: 30
text: watermark.visible ? "Hide watermark" : "Show watermark"
onClicked: {
watermark.visible = !watermark.visible
}
}
Button {
width: 100
height: 30
text: TreelandCaptureManager.record ? "Screenshot" : "Record"
onClicked: {
TreelandCaptureManager.record = !TreelandCaptureManager.record
}
}
Button {
width: 100
height: 30
text: "Finish"
onClicked: {
TreelandCaptureManager.finishSelect()
}
}
}
}
Window {
id: playerWindow
visible: TreelandCaptureManager.recordStarted
width: player.width
height: player.height
color: "black"
Player {
id: player
width: 100
height: 100
captureContext: TreelandCaptureManager.context
}
}
}

View File

@ -1,287 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "capture.h"
#include <private/qguiapplication_p.h>
#include <private/qwaylanddisplay_p.h>
#include <private/qwaylandintegration_p.h>
#include <QPointer>
inline QtWaylandClient::QWaylandIntegration *waylandIntegration()
{
return dynamic_cast<QtWaylandClient::QWaylandIntegration *>(
QGuiApplicationPrivate::platformIntegration());
}
inline QPointer<QtWaylandClient::QWaylandDisplay> waylandDisplay()
{
return waylandIntegration()->display();
}
TreelandCaptureManager *TreelandCaptureManager::instance()
{
static TreelandCaptureManager manager;
return &manager;
}
TreelandCaptureManager *TreelandCaptureManager::create(QQmlEngine *, QJSEngine *)
{
auto manager = instance();
QQmlEngine::setObjectOwnership(manager, QQmlEngine::CppOwnership);
return manager;
}
TreelandCaptureManager::TreelandCaptureManager()
: QWaylandClientExtensionTemplate<TreelandCaptureManager>(1)
, QtWayland::treeland_capture_manager_v1()
{
connect(this, &TreelandCaptureManager::activeChanged, this, [this] {
if (!isActive()) {
delete m_context;
}
});
}
TreelandCaptureContext *TreelandCaptureManager::ensureContext()
{
if (m_context)
return m_context;
auto context = get_context();
m_context = new TreelandCaptureContext(context, this);
connect(m_context, &TreelandCaptureContext::destroyed, this, [this] {
m_context = nullptr;
Q_EMIT contextChanged();
});
Q_EMIT contextChanged();
return m_context;
}
void TreelandCaptureContext::treeland_capture_context_v1_source_ready(int32_t region_x,
int32_t region_y,
uint32_t region_width,
uint32_t region_height,
uint32_t source_type)
{
m_captureRegion = QRect(region_x, region_y, region_width, region_height);
m_sourceType = static_cast<QtWayland::treeland_capture_context_v1::source_type>(source_type);
Q_EMIT captureRegionChanged();
Q_EMIT sourceReady(QRect(region_x, region_y, region_width, region_height), source_type);
}
void TreelandCaptureContext::treeland_capture_context_v1_source_failed(uint32_t reason)
{
Q_EMIT sourceFailed(reason);
}
TreelandCaptureFrame *TreelandCaptureContext::ensureFrame()
{
if (m_frame)
return m_frame;
auto object = QtWayland::treeland_capture_context_v1::capture();
m_frame = new TreelandCaptureFrame(object, this);
connect(m_frame, &TreelandCaptureFrame::destroyed, this, [this] {
m_frame = nullptr;
Q_EMIT frameChanged();
});
Q_EMIT frameChanged();
return m_frame;
}
TreelandCaptureContext::TreelandCaptureContext(::treeland_capture_context_v1 *object,
QObject *parent)
: QObject(parent)
, QtWayland::treeland_capture_context_v1(object)
{
}
TreelandCaptureContext::~TreelandCaptureContext()
{
delete m_frame;
delete m_session;
destroy();
}
void TreelandCaptureContext::selectSource(uint32_t sourceHint,
bool freeze,
bool withCursor,
::wl_surface *mask)
{
select_source(sourceHint, freeze, withCursor, mask);
}
TreelandCaptureSession *TreelandCaptureContext::ensureSession()
{
if (m_session)
return m_session;
auto object = create_session();
m_session = new TreelandCaptureSession(object, this);
connect(m_session, &TreelandCaptureSession::destroyed, this, [this] {
m_session = nullptr;
Q_EMIT sessionChanged();
});
Q_EMIT sessionChanged();
return m_session;
}
TreelandCaptureFrame::TreelandCaptureFrame(::treeland_capture_frame_v1 *object, QObject *parent)
: QObject(parent)
, QtWayland::treeland_capture_frame_v1(object)
, m_shmBuffer(nullptr)
, m_pendingShmBuffer(nullptr)
{
}
TreelandCaptureFrame::~TreelandCaptureFrame()
{
delete m_shmBuffer;
delete m_pendingShmBuffer;
destroy();
}
void TreelandCaptureFrame::treeland_capture_frame_v1_buffer(uint32_t format,
uint32_t width,
uint32_t height,
uint32_t stride)
{
if (stride != width * 4) {
qDebug() << "Receive a buffer format which is not compatible with "
"QWaylandShmBuffer."
<< "format:" << format << "width:" << width << "height:" << height
<< "stride:" << stride;
return;
}
if (m_pendingShmBuffer)
return; // We only need one supported format
m_pendingShmBuffer = new QtWaylandClient::QWaylandShmBuffer(
waylandDisplay(),
QSize(width, height),
QtWaylandClient::QWaylandShm::formatFrom(static_cast<::wl_shm_format>(format)));
copy(m_pendingShmBuffer->buffer());
}
void TreelandCaptureFrame::treeland_capture_frame_v1_flags(uint32_t flags)
{
m_flags = flags;
}
void TreelandCaptureFrame::treeland_capture_frame_v1_ready()
{
if (m_shmBuffer)
delete m_shmBuffer;
m_shmBuffer = m_pendingShmBuffer;
m_pendingShmBuffer = nullptr;
Q_EMIT ready(*m_shmBuffer->image());
}
void TreelandCaptureFrame::treeland_capture_frame_v1_failed()
{
Q_EMIT failed();
}
TreelandCaptureSession::TreelandCaptureSession(::treeland_capture_session_v1 *object,
QObject *parent)
: QObject(parent)
, QtWayland::treeland_capture_session_v1(object)
{
}
TreelandCaptureSession::~TreelandCaptureSession() { }
void TreelandCaptureSession::start()
{
QtWayland::treeland_capture_session_v1::start();
m_started = true;
Q_EMIT started();
}
void TreelandCaptureSession::doneFrame()
{
// Note: Must close all fds here in the client.
for (const auto &object : std::as_const(objects())) {
close(object.fd);
}
m_objects.clear();
frame_done(m_tvSecHi, m_tvSecLo, m_tvUsec);
m_frameValid = false;
Q_EMIT invalid();
}
void TreelandCaptureSession::treeland_capture_session_v1_frame(int32_t offset_x,
int32_t offset_y,
uint32_t width,
uint32_t height,
uint32_t buffer_flags,
uint32_t flags,
uint32_t format,
uint32_t mod_high,
uint32_t mod_low,
uint32_t num_objects)
{
m_objects.clear();
m_objects.reserve(num_objects);
m_offset = { offset_x, offset_y };
m_bufferWidth = width;
m_bufferHeight = height;
m_bufferFlags = buffer_flags;
m_bufferFormat = format;
m_flags = static_cast<QtWayland::treeland_capture_session_v1::flags>(flags);
m_modifierUnion.modLow = mod_low;
m_modifierUnion.modHigh = mod_high;
}
void TreelandCaptureSession::treeland_capture_session_v1_object(uint32_t index,
int32_t fd,
uint32_t size,
uint32_t offset,
uint32_t stride,
uint32_t plane_index)
{
m_objects.push_back({ .index = index,
.fd = fd,
.size = size,
.offset = offset,
.stride = stride,
.planeIndex = plane_index });
}
void TreelandCaptureSession::treeland_capture_session_v1_ready(uint32_t tv_sec_hi,
uint32_t tv_sec_lo,
uint32_t tv_nsec)
{
m_tvSecHi = tv_sec_hi;
m_tvSecLo = tv_sec_lo;
m_tvUsec = tv_nsec;
m_frameValid = true;
Q_EMIT ready();
}
void TreelandCaptureSession::treeland_capture_session_v1_cancel(uint32_t reason)
{
if (reason == QtWayland::treeland_capture_session_v1::cancel_reason_permanent) {
for (const auto &object : std::as_const(objects())) {
close(object.fd);
}
m_objects.clear();
} else {
doneFrame();
}
}
void TreelandCaptureManager::setRecord(bool newRecord)
{
if (m_record == newRecord)
return;
m_record = newRecord;
Q_EMIT recordChanged();
}
bool TreelandCaptureManager::recordStarted() const
{
if (m_context && m_context->session()) {
return m_context->session()->started();
} else {
return false;
}
}

View File

@ -1,273 +0,0 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#pragma once
#include "qwayland-treeland-capture-unstable-v1.h"
#include <private/qwaylandclientextension_p.h>
#include <private/qwaylandshmbackingstore_p.h>
#include <QQmlEngine>
#include <qqmlregistration.h>
class TreelandCaptureFrame
: public QObject
, public QtWayland::treeland_capture_frame_v1
{
Q_OBJECT
QML_ANONYMOUS
public:
TreelandCaptureFrame(struct ::treeland_capture_frame_v1 *object, QObject *parent = nullptr);
~TreelandCaptureFrame() override;
inline uint flags() const
{
return m_flags;
}
Q_SIGNALS:
void ready(QImage image);
void failed();
protected:
void treeland_capture_frame_v1_buffer(uint32_t format,
uint32_t width,
uint32_t height,
uint32_t stride) override;
void treeland_capture_frame_v1_flags(uint32_t flags) override;
void treeland_capture_frame_v1_ready() override;
void treeland_capture_frame_v1_failed() override;
private:
QtWaylandClient::QWaylandShmBuffer *m_shmBuffer{ nullptr };
QtWaylandClient::QWaylandShmBuffer *m_pendingShmBuffer{ nullptr };
uint m_flags;
};
struct FrameObject
{
uint32_t index;
int32_t fd;
uint32_t size;
uint32_t offset;
uint32_t stride;
uint32_t planeIndex;
};
union ModifierUnion
{
struct
{
uint32_t modLow;
uint32_t modHigh;
};
uint64_t modifier;
};
class TreelandCaptureSession
: public QObject
, public QtWayland::treeland_capture_session_v1
{
Q_OBJECT
QML_ANONYMOUS
Q_PROPERTY(bool started READ started NOTIFY startedChanged FINAL)
public:
explicit TreelandCaptureSession(::treeland_capture_session_v1 *object,
QObject *parent = nullptr);
~TreelandCaptureSession() override;
inline uint bufferWidth() const
{
return m_bufferWidth;
}
inline uint bufferHeight() const
{
return m_bufferHeight;
}
inline uint bufferFormat() const
{
return m_bufferFormat;
}
inline uint bufferFlags() const
{
return m_bufferFlags;
}
inline const QList<FrameObject> &objects() const
{
return m_objects;
}
inline ModifierUnion modifierUnion() const
{
return m_modifierUnion;
}
inline bool started() const
{
return m_started;
}
void start();
void doneFrame();
inline bool frameValid() const
{
return m_frameValid;
}
Q_SIGNALS:
void invalid();
void ready();
void startedChanged();
protected:
void treeland_capture_session_v1_frame(int32_t offset_x,
int32_t offset_y,
uint32_t width,
uint32_t height,
uint32_t buffer_flags,
uint32_t flags,
uint32_t format,
uint32_t mod_high,
uint32_t mod_low,
uint32_t num_objects) override;
void treeland_capture_session_v1_object(uint32_t index,
int32_t fd,
uint32_t size,
uint32_t offset,
uint32_t stride,
uint32_t plane_index) override;
void treeland_capture_session_v1_ready(uint32_t tv_sec_hi,
uint32_t tv_sec_lo,
uint32_t tv_nsec) override;
void treeland_capture_session_v1_cancel(uint32_t reason) override;
private:
QPoint m_offset;
uint m_bufferWidth;
uint m_bufferHeight;
uint m_bufferFlags;
uint m_bufferFormat;
ModifierUnion m_modifierUnion;
QList<FrameObject> m_objects;
QtWayland::treeland_capture_session_v1::flags m_flags;
bool m_started{ false };
uint32_t m_tvSecHi;
uint32_t m_tvSecLo;
uint32_t m_tvUsec;
bool m_frameValid{ false };
};
class TreelandCaptureContext
: public QObject
, public QtWayland::treeland_capture_context_v1
{
Q_OBJECT
QML_ANONYMOUS
Q_PROPERTY(TreelandCaptureFrame* frame READ frame NOTIFY frameChanged FINAL)
Q_PROPERTY(TreelandCaptureSession* session READ session NOTIFY sessionChanged FINAL)
Q_PROPERTY(QRectF captureRegion READ captureRegion NOTIFY captureRegionChanged FINAL)
QML_UNCREATABLE("Managed by C++.")
public:
using QtWayland::treeland_capture_context_v1::source_type;
explicit TreelandCaptureContext(struct ::treeland_capture_context_v1 *object,
QObject *parent = nullptr);
~TreelandCaptureContext() override;
inline QRectF captureRegion() const
{
return m_captureRegion;
}
inline QtWayland::treeland_capture_context_v1::source_type sourceType() const
{
return m_sourceType;
}
inline TreelandCaptureFrame *frame() const
{
return m_frame;
}
inline TreelandCaptureSession *session() const
{
return m_session;
}
void selectSource(uint32_t sourceHint, bool freeze, bool withCursor, ::wl_surface *mask);
TreelandCaptureFrame *ensureFrame();
TreelandCaptureSession *ensureSession();
Q_SIGNALS:
void sourceReady(QRect region, uint32_t sourceType);
void sourceFailed(uint32_t reason);
void frameChanged();
void sessionChanged();
void captureRegionChanged();
protected:
void treeland_capture_context_v1_source_ready(int32_t region_x,
int32_t region_y,
uint32_t region_width,
uint32_t region_height,
uint32_t source_type) override;
void treeland_capture_context_v1_source_failed(uint32_t reason) override;
private:
QRect m_captureRegion;
QtWayland::treeland_capture_context_v1::source_type m_sourceType;
TreelandCaptureFrame *m_frame{ nullptr };
TreelandCaptureSession *m_session{ nullptr };
};
class TreelandCaptureManager
: public QWaylandClientExtensionTemplate<TreelandCaptureManager>
, public QtWayland::treeland_capture_manager_v1
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Managed by C++.")
Q_PROPERTY(TreelandCaptureContext* context READ context NOTIFY contextChanged FINAL)
Q_PROPERTY(bool record READ record WRITE setRecord NOTIFY recordChanged FINAL)
Q_PROPERTY(bool recordStarted READ recordStarted NOTIFY recordStartedChanged FINAL)
public:
static TreelandCaptureManager *instance();
static TreelandCaptureManager *create(QQmlEngine *, QJSEngine *);
inline TreelandCaptureContext *context() const
{
return m_context;
}
TreelandCaptureContext *ensureContext();
inline bool record() const
{
return m_record;
}
void setRecord(bool newRecord);
bool recordStarted() const;
Q_SIGNALS:
void contextChanged();
void recordChanged();
void finishSelect();
void recordStartedChanged();
private:
TreelandCaptureManager();
TreelandCaptureContext *m_context{ nullptr };
bool m_record{ false };
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,109 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "capture.h"
#include <private/qwaylandwindow_p.h>
#include <QDir>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
#include <QQuickWindow>
#include <QStandardPaths>
#include <QTimer>
int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QQuickStyle::setStyle("Material");
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
auto manager = TreelandCaptureManager::instance();
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() {
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
auto captureWithMask = [&app, manager](::wl_surface *mask) {
auto captureContext = manager->ensureContext();
if (!captureContext) {
app.exit(-1);
Q_UNREACHABLE();
}
captureContext->selectSource(TreelandCaptureContext::source_type_output
| TreelandCaptureContext::source_type_window
| TreelandCaptureContext::source_type_region,
true,
false,
mask);
QObject::connect(
manager,
&TreelandCaptureManager::finishSelect,
manager,
[&app, captureContext, manager] {
if (manager->record()) {
auto session = captureContext->ensureSession();
session->start();
QTimer::singleShot(1000, manager, [manager] {
Q_EMIT manager->recordStartedChanged();
});
} else {
auto frame = captureContext->ensureFrame();
QImage result;
QEventLoop loop;
QObject::connect(frame,
&TreelandCaptureFrame::ready,
&app,
[&result, &loop](QImage image) {
result = image;
loop.quit();
});
QObject::connect(frame, &TreelandCaptureFrame::failed, &app, [&loop] {
loop.quit();
});
loop.exec();
if (result.isNull())
app.exit(-1);
auto saveBasePath =
QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
QDir saveBaseDir(saveBasePath);
if (!saveBaseDir.exists())
app.exit(-1);
QString picName =
"portal screenshot - " + QDateTime::currentDateTime().toString() + ".png";
if (result.save(saveBaseDir.absoluteFilePath(picName), "PNG")) {
qDebug() << saveBaseDir.absoluteFilePath(picName);
delete TreelandCaptureManager::instance()->context();
app.quit();
} else {
delete TreelandCaptureManager::instance()->context();
app.exit(-1);
}
}
});
};
QObject::connect(&engine,
&QQmlApplicationEngine::objectCreated,
manager,
[&app, manager, captureWithMask](QObject *object, const QUrl &) {
if (auto canvasWindow = qobject_cast<QQuickWindow *>(object)) {
auto waylandWindow = static_cast<QtWaylandClient::QWaylandWindow *>(
canvasWindow->handle());
auto mask = waylandWindow ? waylandWindow->surface() : nullptr;
if (manager->isActive()) {
captureWithMask(mask);
} else {
QObject::connect(manager,
&TreelandCaptureManager::activeChanged,
manager,
std::bind(captureWithMask, mask));
}
}
});
engine.loadFromModule("capture", "Main");
return app.exec();
}

View File

@ -1,365 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "player.h"
#include "capture.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <libdrm/drm_fourcc.h>
#include <rhi/qrhi.h>
#include <QSGImageNode>
#include <QSGTexture>
#include <unistd.h>
Player::Player()
{
setFlag(QQuickItem::ItemHasContents);
}
TreelandCaptureContext *Player::captureContext() const
{
return m_captureContext;
}
void Player::setCaptureContext(TreelandCaptureContext *context)
{
if (context == m_captureContext)
return;
if (m_captureContext) {
m_captureContext->disconnect(this);
}
m_captureContext = context;
if (m_captureContext) {
connect(m_captureContext.data(),
&TreelandCaptureContext::destroyed,
this,
std::bind(&Player::setCaptureContext, this, nullptr));
if (m_captureContext->session()) {
connect(m_captureContext->session(),
&TreelandCaptureSession::ready,
this,
&Player::update);
} else {
connect(m_captureContext, &TreelandCaptureContext::sessionChanged, this, [this] {
if (m_captureContext->session())
connect(m_captureContext->session(),
&TreelandCaptureSession::ready,
this,
&Player::update);
});
}
connect(m_captureContext.data(),
&TreelandCaptureContext::sourceReady,
this,
&Player::updateGeometry);
}
Q_EMIT captureContextChanged();
}
QSGNode *Player::updatePaintNode(QSGNode *old, [[maybe_unused]] UpdatePaintNodeData *data)
{
ensureDebugLogger();
if (!m_captureContext || !m_captureContext->session()
|| !m_captureContext->session()->started())
return nullptr;
updateTexture();
auto node = static_cast<QSGImageNode *>(old);
if (Q_UNLIKELY(!node) && m_rhiTexture != nullptr) {
node = window()->createImageNode();
node->setOwnsTexture(false);
node->setTexture(&m_texture);
} else if (m_rhiTexture != nullptr) {
node->markDirty(QSGNode::DirtyMaterial);
} else {
return nullptr;
}
QRectF sourceRect;
if (m_captureContext->sourceType()
== QtWayland::treeland_capture_context_v1::source_type_window) {
sourceRect = QRectF({ 0, 0 }, m_texture.textureSize());
} else {
sourceRect = m_captureContext->captureRegion();
}
qInfo() << "sourceRect" << sourceRect << "textureSize" << m_texture.textureSize();
node->setSourceRect(sourceRect);
node->setRect(boundingRect());
node->setFiltering(QSGTexture::Linear);
node->setMipmapFiltering(QSGTexture::None);
return node;
}
#define CASE_STR(value) \
case value: \
return #value;
static const char *eglGetErrorString(EGLint error)
{
switch (error) {
CASE_STR(EGL_SUCCESS)
CASE_STR(EGL_NOT_INITIALIZED)
CASE_STR(EGL_BAD_ACCESS)
CASE_STR(EGL_BAD_ALLOC)
CASE_STR(EGL_BAD_ATTRIBUTE)
CASE_STR(EGL_BAD_CONTEXT)
CASE_STR(EGL_BAD_CONFIG)
CASE_STR(EGL_BAD_CURRENT_SURFACE)
CASE_STR(EGL_BAD_DISPLAY)
CASE_STR(EGL_BAD_SURFACE)
CASE_STR(EGL_BAD_MATCH)
CASE_STR(EGL_BAD_PARAMETER)
CASE_STR(EGL_BAD_NATIVE_PIXMAP)
CASE_STR(EGL_BAD_NATIVE_WINDOW)
CASE_STR(EGL_CONTEXT_LOST)
default:
return "Unknown";
}
}
[[maybe_unused]] static const char *drmFormatString(int fourcc)
{
switch (fourcc) {
CASE_STR(DRM_FORMAT_R8)
CASE_STR(DRM_FORMAT_RG88)
CASE_STR(DRM_FORMAT_GR88)
CASE_STR(DRM_FORMAT_R16)
CASE_STR(DRM_FORMAT_GR1616)
CASE_STR(DRM_FORMAT_RGB332)
CASE_STR(DRM_FORMAT_BGR233)
CASE_STR(DRM_FORMAT_XRGB4444)
CASE_STR(DRM_FORMAT_XBGR4444)
CASE_STR(DRM_FORMAT_RGBX4444)
CASE_STR(DRM_FORMAT_BGRX4444)
CASE_STR(DRM_FORMAT_ARGB4444)
CASE_STR(DRM_FORMAT_ABGR4444)
CASE_STR(DRM_FORMAT_RGBA4444)
CASE_STR(DRM_FORMAT_BGRA4444)
CASE_STR(DRM_FORMAT_XRGB1555)
CASE_STR(DRM_FORMAT_XBGR1555)
CASE_STR(DRM_FORMAT_RGBX5551)
CASE_STR(DRM_FORMAT_BGRX5551)
CASE_STR(DRM_FORMAT_ARGB1555)
CASE_STR(DRM_FORMAT_ABGR1555)
CASE_STR(DRM_FORMAT_RGBA5551)
CASE_STR(DRM_FORMAT_BGRA5551)
CASE_STR(DRM_FORMAT_RGB565)
CASE_STR(DRM_FORMAT_BGR565)
CASE_STR(DRM_FORMAT_RGB888)
CASE_STR(DRM_FORMAT_BGR888)
CASE_STR(DRM_FORMAT_XRGB8888)
CASE_STR(DRM_FORMAT_XBGR8888)
CASE_STR(DRM_FORMAT_RGBX8888)
CASE_STR(DRM_FORMAT_BGRX8888)
CASE_STR(DRM_FORMAT_ARGB8888)
CASE_STR(DRM_FORMAT_ABGR8888)
CASE_STR(DRM_FORMAT_RGBA8888)
CASE_STR(DRM_FORMAT_BGRA8888)
CASE_STR(DRM_FORMAT_XRGB2101010)
CASE_STR(DRM_FORMAT_XBGR2101010)
CASE_STR(DRM_FORMAT_RGBX1010102)
CASE_STR(DRM_FORMAT_BGRX1010102)
CASE_STR(DRM_FORMAT_ARGB2101010)
CASE_STR(DRM_FORMAT_ABGR2101010)
CASE_STR(DRM_FORMAT_RGBA1010102)
CASE_STR(DRM_FORMAT_BGRA1010102)
CASE_STR(DRM_FORMAT_ABGR16161616)
CASE_STR(DRM_FORMAT_XBGR16161616)
CASE_STR(DRM_FORMAT_XBGR16161616F)
CASE_STR(DRM_FORMAT_ABGR16161616F)
CASE_STR(DRM_FORMAT_YUYV)
CASE_STR(DRM_FORMAT_YVYU)
CASE_STR(DRM_FORMAT_UYVY)
CASE_STR(DRM_FORMAT_VYUY)
CASE_STR(DRM_FORMAT_AYUV)
CASE_STR(DRM_FORMAT_XYUV8888)
CASE_STR(DRM_FORMAT_Y210)
CASE_STR(DRM_FORMAT_Y212)
CASE_STR(DRM_FORMAT_Y216)
CASE_STR(DRM_FORMAT_Y410)
CASE_STR(DRM_FORMAT_Y412)
CASE_STR(DRM_FORMAT_Y416)
CASE_STR(DRM_FORMAT_NV12)
CASE_STR(DRM_FORMAT_NV21)
CASE_STR(DRM_FORMAT_NV16)
CASE_STR(DRM_FORMAT_NV61)
CASE_STR(DRM_FORMAT_P010)
CASE_STR(DRM_FORMAT_P012)
CASE_STR(DRM_FORMAT_P016)
CASE_STR(DRM_FORMAT_P030)
CASE_STR(DRM_FORMAT_YUV410)
CASE_STR(DRM_FORMAT_YVU410)
CASE_STR(DRM_FORMAT_YUV411)
CASE_STR(DRM_FORMAT_YVU411)
CASE_STR(DRM_FORMAT_YUV420)
CASE_STR(DRM_FORMAT_YVU420)
CASE_STR(DRM_FORMAT_YUV422)
CASE_STR(DRM_FORMAT_YVU422)
CASE_STR(DRM_FORMAT_YUV444)
CASE_STR(DRM_FORMAT_YVU444)
default:
return "Unknown";
}
}
#undef CASE_STR
void Player::updateTexture()
{
if (!m_captureContext->session()->frameValid())
return;
auto glContext = QOpenGLContext::currentContext();
Q_ASSERT(glContext);
auto eglContext = glContext->nativeInterface<QNativeInterface::QEGLContext>();
Q_ASSERT(eglContext);
EGLImage eglImage;
EGLAttrib attribs[47];
int atti = 0;
attribs[atti++] = EGL_WIDTH;
attribs[atti++] = m_captureContext->session()->bufferWidth();
attribs[atti++] = EGL_HEIGHT;
attribs[atti++] = m_captureContext->session()->bufferHeight();
attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
attribs[atti++] = m_captureContext->session()->bufferFormat();
auto objects = m_captureContext->session()->objects();
auto nPlanes = objects.size();
if (nPlanes > 0) {
attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
attribs[atti++] = objects[0].fd;
attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
attribs[atti++] = objects[0].offset;
attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
attribs[atti++] = objects[0].stride;
if (m_captureContext->session()->modifierUnion().modifier) {
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
attribs[atti++] = m_captureContext->session()->modifierUnion().modLow;
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
attribs[atti++] = m_captureContext->session()->modifierUnion().modHigh;
}
}
if (nPlanes > 1) {
attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT;
attribs[atti++] = objects[1].fd;
attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
attribs[atti++] = objects[1].offset;
attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
attribs[atti++] = objects[1].stride;
if (m_captureContext->session()->modifierUnion().modifier) {
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
attribs[atti++] = m_captureContext->session()->modifierUnion().modLow;
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
attribs[atti++] = m_captureContext->session()->modifierUnion().modHigh;
}
}
if (nPlanes > 2) {
attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT;
attribs[atti++] = objects[2].fd;
attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
attribs[atti++] = objects[2].offset;
attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
attribs[atti++] = objects[2].stride;
if (m_captureContext->session()->modifierUnion().modifier) {
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
attribs[atti++] = m_captureContext->session()->modifierUnion().modLow;
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
attribs[atti++] = m_captureContext->session()->modifierUnion().modHigh;
}
}
if (nPlanes > 3) {
attribs[atti++] = EGL_DMA_BUF_PLANE3_FD_EXT;
attribs[atti++] = objects[3].fd;
attribs[atti++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
attribs[atti++] = objects[3].offset;
attribs[atti++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
attribs[atti++] = objects[3].stride;
if (m_captureContext->session()->modifierUnion().modifier) {
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
attribs[atti++] = m_captureContext->session()->modifierUnion().modLow;
attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
attribs[atti++] = m_captureContext->session()->modifierUnion().modHigh;
}
}
attribs[atti++] = EGL_NONE;
eglImage =
eglCreateImage(eglContext->display(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, 0, attribs);
if (eglImage == EGL_NO_IMAGE) {
qWarning() << eglGetErrorString(eglGetError());
m_captureContext->session()->doneFrame();
return;
}
Q_ASSERT_X(window(), __func__, "Window should be ready for rhi.");
if (m_rhiTexture) {
m_texture.setTexture(nullptr);
delete m_rhiTexture;
}
m_rhiTexture =
window()->rhi()->newTexture(QRhiTexture::RGBA8,
QSize{ int(m_captureContext->session()->bufferWidth()),
int(m_captureContext->session()->bufferHeight()) },
1,
QRhiTexture::TextureArray);
glBindTexture(GL_TEXTURE_2D, m_rhiTexture->nativeTexture().object);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
m_texture.setTexture(m_rhiTexture);
m_texture.setTextureSize(QSize{ int(m_captureContext->session()->bufferWidth()),
int(m_captureContext->session()->bufferHeight()) });
m_texture.setOwnsTexture(false);
glBindTexture(GL_TEXTURE_2D, 0);
eglDestroyImage(eglContext->display(), eglImage);
m_captureContext->session()->doneFrame();
}
void Player::updateGeometry()
{
Q_ASSERT(m_captureContext);
setWidth(m_captureContext->captureRegion().width());
setHeight(m_captureContext->captureRegion().height());
}
static void EGLAPIENTRY debugCallback(EGLenum error,
[[maybe_unused]] const char *command,
[[maybe_unused]] EGLint messageType,
[[maybe_unused]] EGLLabelKHR threadLabel,
[[maybe_unused]] EGLLabelKHR objectLabel,
const char *message)
{
qInfo() << "EGL Debug:" << message << "(Error Code:" << error << ")";
}
void Player::ensureDebugLogger()
{
if (m_loggerInitialized)
return;
if (QOpenGLContext::currentContext()->hasExtension(QByteArrayLiteral("GL_KHR_debug"))) {
const EGLAttrib debugAttribs[] = {
EGL_DEBUG_MSG_CRITICAL_KHR,
EGL_TRUE,
EGL_DEBUG_MSG_ERROR_KHR,
EGL_TRUE,
EGL_DEBUG_MSG_WARN_KHR,
EGL_TRUE,
EGL_DEBUG_MSG_INFO_KHR,
EGL_TRUE,
EGL_NONE,
};
PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR =
(PFNEGLDEBUGMESSAGECONTROLKHRPROC)eglGetProcAddress("eglDebugMessageControlKHR");
if (eglDebugMessageControlKHR) {
eglDebugMessageControlKHR(debugCallback, debugAttribs);
} else {
qCritical() << "Failed to get eglDebugMessageControlKHR function.";
}
} else {
qCritical() << "GL_KHR_debug is not supported.";
}
m_loggerInitialized = true;
}

View File

@ -1,38 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#pragma once
#include <private/qsgplaintexture_p.h>
#include <QQuickItem>
class QSGPlainTexture;
class QRhiTexture;
class TreelandCaptureContext;
class Player : public QQuickItem
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(TreelandCaptureContext* captureContext READ captureContext WRITE setCaptureContext NOTIFY captureContextChanged FINAL)
public:
Player();
TreelandCaptureContext *captureContext() const;
void setCaptureContext(TreelandCaptureContext *context);
Q_SIGNALS:
void captureContextChanged();
protected:
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private:
void updateTexture();
void updateGeometry();
void ensureDebugLogger();
QSGPlainTexture m_texture;
QRhiTexture *m_rhiTexture{ nullptr };
QPointer<TreelandCaptureContext> m_captureContext{};
bool m_loggerInitialized{ false };
};

View File

@ -1,16 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "subwindow.h"
SubWindow::SubWindow() { }
QQuickWindow *SubWindow::parent() const
{
return qobject_cast<QQuickWindow *>(QWindow::parent());
}
void SubWindow::setParent(QQuickWindow *w)
{
QWindow::setParent(w);
Q_EMIT parentChanged();
}

View File

@ -1,21 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QQuickWindow>
class SubWindow : public QQuickWindow
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QQuickWindow *parent READ parent WRITE setParent NOTIFY parentChanged FINAL)
Q_SIGNALS:
void parentChanged();
public:
SubWindow();
QQuickWindow *parent() const;
void setParent(QQuickWindow *w);
};

View File

@ -1,35 +0,0 @@
find_package(Qt6 REQUIRED COMPONENTS WaylandClient Quick)
find_package(Qt6 COMPONENTS WaylandClientPrivate QUIET)
find_package(TreelandProtocols REQUIRED)
set(BIN_NAME test-multitaskview)
qt_standard_project_setup(REQUIRES 6.5)
qt_add_executable(${BIN_NAME}
main.cpp
)
qt_add_qml_module(${BIN_NAME}
URI test.multitaskview
VERSION 1.0
QML_FILES
Main.qml
SOURCES
ddeshell.h
ddeshell.cpp
)
qt_generate_wayland_protocol_client_sources(${BIN_NAME}
FILES
${TREELAND_PROTOCOLS_DATA_DIR}/treeland-dde-shell-v1.xml
)
target_link_libraries(${BIN_NAME}
PRIVATE
Qt6::Quick
Qt6::WaylandClient
Qt6::WaylandClientPrivate
)
install(TARGETS ${BIN_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

View File

@ -1,43 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import test.multitaskview
Window {
width: 400
height: 200
visible: true
title: qsTr("test-multitaskview")
Multitaskview {
id: multitaskview
}
Timer {
id: timer
interval: 5000
onTriggered: {
multitaskview.toggle()
}
}
ColumnLayout {
anchors.fill: parent
Button {
text: "Show multitaskview with hide timer(5s)"
visible: multitaskview.ready
onClicked: {
multitaskview.toggle()
timer.restart()
}
Layout.alignment: Qt.AlignCenter
}
Button {
text: "Show multitaskview"
visible: multitaskview.ready
onClicked: {
multitaskview.toggle()
}
Layout.alignment: Qt.AlignCenter
}
}
}

View File

@ -1,34 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "ddeshell.h"
void Multitaskview::toggle()
{
QtWayland::treeland_multitaskview_v1::toggle();
}
Multitaskview::Multitaskview()
: QWaylandClientExtensionTemplate<Multitaskview>(1)
, QtWayland::treeland_multitaskview_v1()
, m_manager(new DDEShell)
{
connect(
m_manager,
&DDEShell::activeChanged,
this,
[this]() {
if (m_manager->isActive()) {
auto object = m_manager->get_treeland_multitaskview();
Q_ASSERT(object);
init(object);
Q_EMIT readyChanged();
}
},
Qt::QueuedConnection);
}
Multitaskview::~Multitaskview()
{
m_manager->deleteLater();
}

View File

@ -1,48 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#pragma once
#include "qwayland-treeland-dde-shell-v1.h"
#include <qwaylandclientextension.h>
#include <qqmlintegration.h>
#include <qtmetamacros.h>
class DDEShell
: public QWaylandClientExtensionTemplate<DDEShell>
, public QtWayland::treeland_dde_shell_manager_v1
{
Q_OBJECT
public:
explicit DDEShell()
: QWaylandClientExtensionTemplate<DDEShell>(1)
{
}
};
class Multitaskview
: public QWaylandClientExtensionTemplate<Multitaskview>
, public QtWayland::treeland_multitaskview_v1
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged FINAL)
bool ready()
{
return object() != nullptr;
}
Q_SIGNALS:
void readyChanged();
public:
explicit Multitaskview();
~Multitaskview();
Q_INVOKABLE void toggle();
private:
DDEShell *m_manager;
};

View File

@ -1,22 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() {
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.loadFromModule("test.multitaskview", "Main");
return app.exec();
}

View File

@ -1,20 +0,0 @@
// Copyright (C) 2024 groveer <guoyao@uniontech.com>.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QQuickItem>
class Q_DECL_HIDDEN EventItem : public QQuickItem
{
Q_OBJECT
QML_NAMED_ELEMENT(EventItem)
public:
explicit EventItem(QQuickItem *parent = nullptr);
inline bool isValid() const
{
return parent();
}
private:
bool event(QEvent *event) override;
};

View File

@ -1,22 +0,0 @@
find_package(Qt6 REQUIRED COMPONENTS WaylandClient Widgets)
find_package(TreelandProtocols REQUIRED)
set(BIN_NAME test-primary-output)
qt_add_executable(${BIN_NAME}
main.cpp
)
qt_generate_wayland_protocol_client_sources(${BIN_NAME}
FILES
${TREELAND_PROTOCOLS_DATA_DIR}treeland-output-manager-v1.xml
)
target_link_libraries(${BIN_NAME}
PRIVATE
Qt6::Gui
Qt6::Widgets
Qt6::WaylandClient
)
install(TARGETS ${BIN_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

View File

@ -1,48 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qwayland-treeland-output-manager-v1.h"
#include <QApplication>
#include <QObject>
#include <QWaylandClientExtension>
class PrimaryOutputV1
: public QWaylandClientExtensionTemplate<PrimaryOutputV1>
, public QtWayland::treeland_output_manager_v1
{
Q_OBJECT
public:
explicit PrimaryOutputV1();
void treeland_output_manager_v1_primary_output(const QString &output_name)
{
qInfo() << "-------Primary Output ----- " << output_name;
}
};
PrimaryOutputV1::PrimaryOutputV1()
: QWaylandClientExtensionTemplate<PrimaryOutputV1>(1)
{
}
// 设置主屏: ./test-primary-output HDMI-0
int main(int argc, char *argv[])
{
qputenv("QT_QPA_PLATFORM", "wayland");
QApplication app(argc, argv);
PrimaryOutputV1 manager;
QObject::connect(&manager, &PrimaryOutputV1::activeChanged, &manager, [&manager, argc, argv] {
if (manager.isActive()) {
if (argc == 2) {
const QString str(argv[1]);
manager.set_primary_output(str);
}
}
});
return app.exec();
}
#include "main.moc"

View File

@ -1,52 +0,0 @@
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Core)
find_package(Qt6 REQUIRED COMPONENTS WaylandClient Quick Core Gui)
find_package(Dtk6 REQUIRED COMPONENTS Declarative)
find_package(TreelandProtocols REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_get_variable(WAYLAND_PROTOCOLS wayland-protocols pkgdatadir)
# Include translation utilities
include(${CMAKE_SOURCE_DIR}/cmake/TranslationUtils.cmake)
set(BIN_NAME test-set-treeland-wallpaper)
qt_add_executable(${BIN_NAME}
main.cpp
)
qt_generate_wayland_protocol_client_sources(${BIN_NAME}
FILES
${TREELAND_PROTOCOLS_DATA_DIR}/treeland-personalization-manager-v1.xml
)
set(QML_FILES
main.qml
Wallpaper.qml
WallpaperCard.qml
WallpaperSetting.qml
PropertyItemDelegate.qml
)
qt_add_qml_module(${BIN_NAME}
URI Wallpaper
VERSION "1.0"
SOURCES
personalizationmangerclient.cpp
personalizationmangerclient.h
wallpapercardmodel.cpp
wallpapercardmodel.h
QML_FILES ${QML_FILES}
SOURCES imagehelper.h imagehelper.cpp
)
# Use translation utilities to setup translations
setup_translations(${BIN_NAME} wallpaper)
target_link_libraries(${BIN_NAME}
PRIVATE
Qt6::Gui
Qt6::WaylandClient
Dtk6::Declarative
)
install(TARGETS ${BIN_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

View File

@ -1,25 +0,0 @@
// Copyright (C) 2024 rewine <luhongxu@deepin.org>.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "imagehelper.h"
#include <QQmlInfo>
ImageHelper::ImageHelper(QObject *parent)
: QObject{ parent }
{
}
bool ImageHelper::isDarkType(const QImage &img)
{
int r = 0, g = 0, b = 0;
for (int i = 0; i < img.width(); i++)
for (int j = 0; j < img.height(); j++) {
r += qRed(img.pixel(i, j));
g += qGreen(img.pixel(i, j));
b += qBlue(img.pixel(i, j));
}
auto size = img.width() * img.height();
float luminance = 0.299 * r / size + 0.587 * g / size + 0.114 * b / size;
return qRound(luminance) <= 170;
}

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ca">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation>Imatge local</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Mostra-ho tot</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation>Imatge del sistema</translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Fons de pantalla</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Fons actual</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Mètode de visualització del fons de pantalla</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation>Estira</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation>Preserva&apos;n l&apos;aspecte</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Si us plau, trieu un fitxer</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Afegiu-hi un fons de pantalla</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Afegiu-hi un directori</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Paràmetres del fons de pantalla</translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="es">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation>Imagen local</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Mostrar todo</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation>Imagen del sistema</translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Fondo de pantalla</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Fondo de pantalla actual</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Modo de visualización de fondo de pantalla</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation>Estirar</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation>Conservar aspecto</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Seleccione un archivo</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Agregar fondo de pantalla</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Agregar directorio</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Configuración del fondo de pantalla</translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="fi">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation>Valokuva</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Näytä kaikki</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation>Valokuva</translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Taustakuva</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Nykyinen taustakuva</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Taustakuvan näyttötapa</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation>Venytetty</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation>Säilytä kuvasuhde</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Valitse tiedosto</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Lisää taustakuva</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Lisää kansio</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Taustakuvan asetukset</translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="fr">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation>Image locale</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Afficher tout</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation>Image système</translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Fond d&apos;écran</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Fond d&apos;écran actuel</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Méthode d&apos;affichage du fond d&apos;écran</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation>Étirement</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation>Conserver l&apos;aspect</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Veuillez choisir un fichier</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Ajouter un fond d&apos;écran</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Ajouter un répertoire</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Paramètres du fond d&apos;écran</translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ja">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation></translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation></translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation></translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation></translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation></translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation></translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation></translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation></translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation></translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation></translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation></translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation></translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="pl">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation>Zdjęcie lokalne</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Pokaż wszystkie</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation>Zdjęcie systemowe</translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Tapeta</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Bieżąca tapeta</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Wyświetlanie tapety</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation>Rozciągnij</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation>Dopasuj</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Wybierz plik</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Dodaj tapetę</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Dodaj katalog</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Ustawienia tapety</translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="pt_BR">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation>Imagem local</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Mostrar tudo</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation>Imagem do sistema</translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Papel de parede</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Papel de parede atual</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Método de exibição de papel de parede</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation>Esticado</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation>Preservar o ajuste do aspecto</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Por favor escolha um arquivo</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Adicionar papel de parede</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Adicionar diretório</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Configurações de papel de parede</translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ru">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Показать все</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Обои</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Текущие обои</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Метод отображения обоев</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Пожалуйста, выберите файл</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Добавить обои</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Добавить папку</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Настройки обоев</translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="sq">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation>Foto Vendore</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Shfaqi Krejt</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation>Foto Sistemi</translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Sfond</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Sfond i Tanishëm</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Metodë Shfaqjeje Sfondi</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation>Shformoje</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Ju lutemi, zgjidhni një kartelë</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Shtoni Sfond</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Shtoni Drejtori</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Rregullime Sfondi</translation>
</message>
</context>
</TS>

View File

@ -1,72 +0,0 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="uk">
<context>
<name>Wallpaper</name>
<message>
<location filename="../Wallpaper.qml" line="48"/>
<source>Local Picture</source>
<translation>Локальне зображення</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="49"/>
<location filename="../Wallpaper.qml" line="62"/>
<source>Show All</source>
<translation>Показати все</translation>
</message>
<message>
<location filename="../Wallpaper.qml" line="61"/>
<source>System Picture</source>
<translation>Загальносистемне зображення</translation>
</message>
</context>
<context>
<name>WallpaperSetting</name>
<message>
<location filename="../WallpaperSetting.qml" line="29"/>
<source>Wallpaper</source>
<translation>Фонове зображення</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="83"/>
<source>Current Wallpaepr</source>
<translation>Поточне фонове зображення</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="93"/>
<source>Wallpaper Display Method</source>
<translation>Спосіб показу фонового зображення</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="100"/>
<source>Stretch</source>
<translation>Розтягнути</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="101"/>
<source>Preserve Aspect Fit</source>
<translation>Зберегти співвідношення розмірів</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="111"/>
<source>Please choose a file</source>
<translation>Будь ласка, виберіть файл</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="126"/>
<source>Add Wallpaper</source>
<translation>Додати фонове зображення</translation>
</message>
<message>
<location filename="../WallpaperSetting.qml" line="135"/>
<source>Add Directory</source>
<translation>Додати каталог</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="14"/>
<source>Wallpaper Settings</source>
<translation>Параметри фонових зображень</translation>
</message>
</context>
</TS>

View File

@ -1,126 +0,0 @@
// Copyright (C) 2023 Dingyuan Zhang <lxz@mkacg.com>.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "personalization_manager.h"
#include <QApplication>
#include <QBoxLayout>
#include <QDebug>
#include <QLabel>
#include <QLineEdit>
#include <QMainWindow>
#include <QMouseEvent>
#include <QPushButton>
class TestWindow : public QWidget
{
Q_OBJECT
public:
TestWindow()
: m_manager(new PersonalizationManager)
{
setWindowTitle("Setting Appearance Client");
QVBoxLayout *mainLayout = new QVBoxLayout;
QHBoxLayout *group1Layout = new QHBoxLayout;
QPushButton *button1 = new QPushButton("set window light theme");
QPushButton *button2 = new QPushButton("set window dark theme");
group1Layout->addWidget(button1);
group1Layout->addWidget(button2);
mainLayout->addLayout(group1Layout);
connect(button1, &QPushButton::clicked, this, [this, button1] {
context->set_window_theme_type(
TREELAND_PERSONALIZATION_APPEARANCE_CONTEXT_V1_THEME_TYPE_LIGHT);
});
connect(button2, &QPushButton::clicked, this, [this, button1] {
context->set_window_theme_type(
TREELAND_PERSONALIZATION_APPEARANCE_CONTEXT_V1_THEME_TYPE_DARK);
});
QLabel *currentWindowTheme = new QLabel;
mainLayout->addWidget(currentWindowTheme);
QLabel *titlebarLabel = new QLabel("titlebar height:");
QLineEdit *titlebarEdit = new QLineEdit;
QHBoxLayout *group2Layout = new QHBoxLayout;
QPushButton *button3 = new QPushButton("set titlebar height");
group2Layout->addWidget(titlebarLabel);
group2Layout->addWidget(titlebarEdit);
group2Layout->addWidget(button3);
mainLayout->addLayout(group2Layout);
connect(button3, &QPushButton::clicked, this, [this, titlebarEdit] {
context->set_window_titlebar_height(titlebarEdit->text().toUInt());
});
mainLayout->addStretch();
connect(m_manager,
&PersonalizationManager::activeChanged,
this,
[this, currentWindowTheme, titlebarEdit] {
qDebug() << "personalization manager active changed";
if (m_manager->isActive()) {
context = new Appearance(m_manager->get_appearance_context());
cursor = new Cursor(m_manager->get_cursor_context());
font = new Font(m_manager->get_font_context());
connect(context,
&Appearance::windowThemeTypeChanged,
this,
[currentWindowTheme](uint32_t type) {
currentWindowTheme->setText(
QString("current window theme type: %1").arg(type));
});
context->get_window_theme_type();
connect(context,
&Appearance::windowTitlebarHeightChanged,
this,
[titlebarEdit](uint32_t height) {
titlebarEdit->blockSignals(true);
titlebarEdit->setText(QString::number(height));
titlebarEdit->blockSignals(false);
qDebug() << "titlebar height changed: " << height;
});
context->get_window_titlebar_height();
font->get_font();
font->get_font_size();
font->get_monospace_font();
}
});
setLayout(mainLayout);
setMinimumSize(400, 300);
}
~TestWindow()
{
if (m_manager != nullptr) {
delete m_manager;
m_manager = nullptr;
}
}
private:
PersonalizationManager *m_manager = nullptr;
Appearance *context = nullptr;
Font *font = nullptr;
Cursor *cursor = nullptr;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TestWindow window;
window.show();
return app.exec();
}
#include "main.moc"

View File

@ -1,98 +0,0 @@
// Copyright (C) 2024 justforlxz <zhangdingyuan@deepin.com>.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "personalization_manager.h"
#include <QDebug>
QT_BEGIN_NAMESPACE
PersonalizationManager::PersonalizationManager()
: QWaylandClientExtensionTemplate<PersonalizationManager>(1)
{
}
Cursor::Cursor(struct ::treeland_personalization_cursor_context_v1 *object)
: QWaylandClientExtensionTemplate<Cursor>(1)
, QtWayland::treeland_personalization_cursor_context_v1(object)
{
}
void Cursor::treeland_personalization_cursor_context_v1_verfity(int32_t success)
{
Q_EMIT verifyChanged(success);
}
void Cursor::treeland_personalization_cursor_context_v1_theme(const QString &name)
{
Q_EMIT themeChanged(name);
}
void Cursor::treeland_personalization_cursor_context_v1_size(uint32_t size)
{
Q_EMIT sizeChanged(size);
}
Font::Font(struct ::treeland_personalization_font_context_v1 *object)
: QWaylandClientExtensionTemplate<Font>(1)
, QtWayland::treeland_personalization_font_context_v1(object)
{
}
void Font::treeland_personalization_font_context_v1_font(const QString &font_name)
{
Q_EMIT fontChanged(font_name);
}
void Font::treeland_personalization_font_context_v1_monospace_font(const QString &font_name)
{
Q_EMIT monoFontChanged(font_name);
}
void Font::treeland_personalization_font_context_v1_font_size(uint32_t font_size)
{
Q_EMIT fontSizeChanged(font_size);
}
Appearance::Appearance(struct ::treeland_personalization_appearance_context_v1 *object)
: QWaylandClientExtensionTemplate<Appearance>(1)
, QtWayland::treeland_personalization_appearance_context_v1(object)
{
}
void Appearance::treeland_personalization_appearance_context_v1_round_corner_radius(int32_t radius)
{
Q_EMIT radiusChanged(radius);
}
void Appearance::treeland_personalization_appearance_context_v1_icon_theme(
const QString &theme_name)
{
Q_EMIT iconThemeChanged(theme_name);
}
void Appearance::treeland_personalization_appearance_context_v1_active_color(
const QString &active_color)
{
Q_EMIT activeColorChanged(active_color);
}
void Appearance::treeland_personalization_appearance_context_v1_window_opacity(uint32_t opacity)
{
Q_EMIT windowOpacityChanged(opacity);
}
void Appearance::treeland_personalization_appearance_context_v1_window_theme_type(uint32_t type)
{
Q_EMIT windowThemeTypeChanged(type);
}
void Appearance::treeland_personalization_appearance_context_v1_window_titlebar_height(
uint32_t height)
{
Q_EMIT windowTitlebarHeightChanged(height);
}
QT_END_NAMESPACE

View File

@ -1,92 +0,0 @@
// Copyright (C) 2024 justforlxz <zhangdingyuan@deepin.com>.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef CUSTOMEXTENSION_H
#define CUSTOMEXTENSION_H
#include "qwayland-treeland-personalization-manager-v1.h"
#include <QtGui/QWindow>
#include <QtWaylandClient/QWaylandClientExtension>
QT_BEGIN_NAMESPACE
class PersonalizationManager
: public QWaylandClientExtensionTemplate<PersonalizationManager>
, public QtWayland::treeland_personalization_manager_v1
{
Q_OBJECT
public:
explicit PersonalizationManager();
};
class Cursor
: public QWaylandClientExtensionTemplate<Cursor>
, public QtWayland::treeland_personalization_cursor_context_v1
{
Q_OBJECT
public:
explicit Cursor(struct ::treeland_personalization_cursor_context_v1 *object);
Q_SIGNALS:
void verifyChanged(int32_t success);
void themeChanged(const QString &name);
void sizeChanged(uint32_t size);
protected:
void treeland_personalization_cursor_context_v1_verfity(int32_t success) override;
void treeland_personalization_cursor_context_v1_theme(const QString &name) override;
void treeland_personalization_cursor_context_v1_size(uint32_t size) override;
};
class Font
: public QWaylandClientExtensionTemplate<Font>
, public QtWayland::treeland_personalization_font_context_v1
{
Q_OBJECT
public:
explicit Font(struct ::treeland_personalization_font_context_v1 *object);
Q_SIGNALS:
void fontChanged(const QString &font_name);
void monoFontChanged(const QString &font_name);
void fontSizeChanged(uint32_t font_size);
protected:
void treeland_personalization_font_context_v1_font(const QString &font_name) override;
void treeland_personalization_font_context_v1_monospace_font(const QString &font_name) override;
void treeland_personalization_font_context_v1_font_size(uint32_t font_size) override;
};
class Appearance
: public QWaylandClientExtensionTemplate<Appearance>
, public QtWayland::treeland_personalization_appearance_context_v1
{
Q_OBJECT
public:
explicit Appearance(struct ::treeland_personalization_appearance_context_v1 *object);
Q_SIGNALS:
void radiusChanged(int32_t radius);
void iconThemeChanged(const QString &name);
void activeColorChanged(const QString &color);
void windowOpacityChanged(uint32_t opacity);
void windowThemeTypeChanged(uint32_t type);
void windowTitlebarHeightChanged(uint32_t height);
protected:
void treeland_personalization_appearance_context_v1_round_corner_radius(
int32_t radius) override;
void treeland_personalization_appearance_context_v1_icon_theme(
const QString &theme_name) override;
void treeland_personalization_appearance_context_v1_active_color(
const QString &active_color) override;
void treeland_personalization_appearance_context_v1_window_opacity(uint32_t opacity) override;
void treeland_personalization_appearance_context_v1_window_theme_type(uint32_t type) override;
void treeland_personalization_appearance_context_v1_window_titlebar_height(
uint32_t height) override;
};
QT_END_NAMESPACE
#endif // CUSTOMEXTENSION_H

View File

@ -1,34 +0,0 @@
find_package(Qt6 REQUIRED COMPONENTS WaylandClient Quick)
find_package(TreelandProtocols REQUIRED)
set(BIN_NAME test-window-picker)
qt_standard_project_setup(REQUIRES 6.5)
qt_add_executable(${BIN_NAME}
main.cpp
)
qt_add_qml_module(${BIN_NAME}
URI windowpicker
VERSION 1.0
QML_FILES
Main.qml
SOURCES
ddeshell.h
ddeshell.cpp
)
qt_generate_wayland_protocol_client_sources(${BIN_NAME}
FILES
${TREELAND_PROTOCOLS_DATA_DIR}/treeland-dde-shell-v1.xml
)
target_link_libraries(${BIN_NAME}
PRIVATE
Qt6::Quick
Qt6::WaylandClient
Qt6::WaylandClientPrivate
)
install(TARGETS ${BIN_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

View File

@ -1,30 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
import QtQuick
import QtQuick.Controls
import windowpicker
Window {
width: 400
height: 200
visible: true
title: qsTr("test-window-picker")
WindowPickerClient {
id: windowPicker
}
Button {
anchors.centerIn: parent
text: "Pick a window"
visible: windowPicker.ready
onClicked: {
windowPicker.pick()
}
}
Text {
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignBottom
font.pixelSize: 30
text: qsTr("Picked window pid:" + windowPicker.pid)
}
}

View File

@ -1,40 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "ddeshell.h"
void WindowPickerClient::pick()
{
QtWayland::treeland_window_picker_v1::pick("Pick window pid");
}
WindowPickerClient::WindowPickerClient()
: QWaylandClientExtensionTemplate<WindowPickerClient>(1)
, QtWayland::treeland_window_picker_v1()
, m_manager(new DDEShell)
{
connect(
m_manager,
&DDEShell::activeChanged,
this,
[this]() {
if (m_manager->isActive()) {
auto object = m_manager->get_treeland_window_picker();
Q_ASSERT(object);
init(object);
Q_EMIT readyChanged();
}
},
Qt::QueuedConnection);
}
WindowPickerClient::~WindowPickerClient()
{
m_manager->deleteLater();
}
void WindowPickerClient::treeland_window_picker_v1_window(int32_t pid)
{
m_pid = pid;
Q_EMIT pidChanged();
}

View File

@ -1,60 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#pragma once
#include "qwayland-treeland-dde-shell-v1.h"
#include <qwaylandclientextension.h>
#include <qqmlintegration.h>
#include <qtmetamacros.h>
class DDEShell
: public QWaylandClientExtensionTemplate<DDEShell>
, public QtWayland::treeland_dde_shell_manager_v1
{
Q_OBJECT
public:
explicit DDEShell()
: QWaylandClientExtensionTemplate<DDEShell>(1)
{
}
};
class WindowPickerClient
: public QWaylandClientExtensionTemplate<WindowPickerClient>
, public QtWayland::treeland_window_picker_v1
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged FINAL)
Q_PROPERTY(int pid READ pid NOTIFY pidChanged FINAL)
int pid() const
{
return m_pid;
}
bool ready()
{
return object() != nullptr;
}
Q_SIGNALS:
void readyChanged();
void pidChanged();
public:
explicit WindowPickerClient();
~WindowPickerClient();
Q_INVOKABLE void pick();
private:
DDEShell *m_manager;
int m_pid{ -1 };
// treeland_window_picker_v1 interface
protected:
void treeland_window_picker_v1_window(int32_t pid) override;
};

View File

@ -1,22 +0,0 @@
// Copyright (C) 2024 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() {
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.loadFromModule("windowpicker", "Main");
return app.exec();
}

View File

@ -13,11 +13,11 @@
]
},
"locked": {
"lastModified": 1753066592,
"narHash": "sha256-jtFBL0yT1fBwatqvRuCvp0LjKOChU4YGmZvMpIIrAmE=",
"lastModified": 1715914341,
"narHash": "sha256-zZf7pdDtN78Iv/MS9DocFdoRI4mXbDpGdViG8fWOQEQ=",
"owner": "linuxdeepin",
"repo": "ddm",
"rev": "e3a27b23cefe51adbfab973043b26959136ea4ad",
"rev": "3405f9abf5a7c1443547c74099a7e918fade2500",
"type": "github"
},
"original": {
@ -31,11 +31,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
@ -46,11 +46,11 @@
},
"nix-filter": {
"locked": {
"lastModified": 1731533336,
"narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=",
"lastModified": 1710156097,
"narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=",
"owner": "numtide",
"repo": "nix-filter",
"rev": "f7653272fd234696ae94229839a99b73c9ab7de0",
"rev": "3342559a24e85fc164b295c3444e8a139924675b",
"type": "github"
},
"original": {
@ -61,27 +61,57 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1752950548,
"narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=",
"lastModified": 1719381159,
"narHash": "sha256-Kp7O8zV0dFNinR9bAwRQ0XG0cmJ3L5/Md4E/uat5aXc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c87b95e25065c028d31a94f06a62927d18763fdf",
"rev": "c4f0f788123973aedb7a88d78109909d9f223ca6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"ref": "master",
"repo": "nixpkgs",
"type": "github"
}
},
"qwlroots": {
"inputs": {
"flake-utils": [
"waylib",
"flake-utils"
],
"nix-filter": [
"waylib",
"nix-filter"
],
"nixpkgs": [
"waylib",
"nixpkgs"
],
"wlroots-master": "wlroots-master"
},
"locked": {
"lastModified": 1718885849,
"narHash": "sha256-AdWxGIGpmhKdaPUoWdPozX8NBgMnOK7qoPm9HYDEXXU=",
"owner": "vioken",
"repo": "qwlroots",
"rev": "09470bbb9720374bc182dd4bdb8ccb913fef9187",
"type": "github"
},
"original": {
"owner": "vioken",
"repo": "qwlroots",
"type": "github"
}
},
"root": {
"inputs": {
"ddm": "ddm",
"flake-utils": "flake-utils",
"nix-filter": "nix-filter",
"nixpkgs": "nixpkgs",
"treeland-protocols": "treeland-protocols"
"waylib": "waylib"
}
},
"systems": {
@ -99,7 +129,7 @@
"type": "github"
}
},
"treeland-protocols": {
"waylib": {
"inputs": {
"flake-utils": [
"flake-utils"
@ -109,21 +139,41 @@
],
"nixpkgs": [
"nixpkgs"
]
],
"qwlroots": "qwlroots"
},
"locked": {
"lastModified": 1737101824,
"narHash": "sha256-keu/J/mEW7VIQ2Nyo9SaOreUYoDdgxONb66c6XN3Gnc=",
"owner": "linuxdeepin",
"repo": "treeland-protocols",
"rev": "b087c563ad5b07f61ebbe2417251839ef6876d45",
"lastModified": 1719287344,
"narHash": "sha256-5GCjH8j7UhzZtCxzjSOq1WZqdnpG1Jf1fVcYD2LvEv8=",
"owner": "vioken",
"repo": "waylib",
"rev": "e138aa2acb5bd69b32b871851f6df4e58301ae2f",
"type": "github"
},
"original": {
"owner": "linuxdeepin",
"repo": "treeland-protocols",
"owner": "vioken",
"repo": "waylib",
"type": "github"
}
},
"wlroots-master": {
"flake": false,
"locked": {
"host": "gitlab.freedesktop.org",
"lastModified": 1716851300,
"narHash": "sha256-cnuBNBbXygiCeRjf3YT0ENx2pGu0knc6SAvk19bLj6A=",
"owner": "wlroots",
"repo": "wlroots",
"rev": "dc5996a8b45362a3add882f4510b535388b17e01",
"type": "gitlab"
},
"original": {
"host": "gitlab.freedesktop.org",
"owner": "wlroots",
"ref": "master",
"repo": "wlroots",
"type": "gitlab"
}
}
},
"root": "root",

View File

@ -2,36 +2,62 @@
description = "A basic flake to help develop treeland";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs.url = "github:NixOS/nixpkgs/master";
flake-utils.url = "github:numtide/flake-utils";
nix-filter.url = "github:numtide/nix-filter";
waylib = {
url = "github:vioken/waylib";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
inputs.nix-filter.follows = "nix-filter";
};
ddm = {
url = "github:linuxdeepin/ddm";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
inputs.nix-filter.follows = "nix-filter";
};
treeland-protocols = {
url = "github:linuxdeepin/treeland-protocols";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
inputs.nix-filter.follows = "nix-filter";
};
};
outputs = { self, nixpkgs, flake-utils, nix-filter, ddm, treeland-protocols }@input:
outputs = { self, nixpkgs, flake-utils, nix-filter, waylib, ddm }@input:
flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" "riscv64-linux" ]
(system:
let
pkgs = nixpkgs.legacyPackages.${system};
treeland = pkgs.qt6Packages.callPackage ./nix {
nix-filter = nix-filter.lib;
waylib = waylib.packages.${system}.default;
ddm = ddm.packages.${system}.default;
};
in
rec {
{
nixosConfigurations.vm = nixpkgs.lib.nixosSystem {
inherit system;
modules = [
{
imports = [ "${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" ];
# TODO: allow set Environment in services.seatd
users.groups.seat = { };
systemd.services.seatd = {
description = "Seat management daemon";
documentation = [ "man:seatd(1)" ];
wantedBy = [ "multi-user.target" ];
restartIfChanged = false;
serviceConfig = {
Type = "notify";
NotifyAccess = "all";
SyslogIdentifier = "seatd";
ExecStart = "${pkgs.sdnotify-wrapper}/bin/sdnotify-wrapper ${pkgs.seatd.bin}/bin/seatd -n 1 -u dde -g dde -l debug";
RestartSec = 1;
Restart = "always";
Environment = "SEATD_VTBOUND=0";
};
};
environment.systemPackages = with pkgs; [
foot
gdb
@ -71,7 +97,7 @@
'';
};
# services.xserver.displayManager.defaultSession = "Treeland";
# services.xserver.displayManager.defaultSession = "TreeLand";
# services.xserver.displayManager.sessionPackages = [ treeland ];
environment.etc."ddm.conf".text = ''
[General]
@ -152,21 +178,15 @@
diskSize = 16384;
resolution = { x = 1920; y = 1080; };
};
system.stateVersion = "25.05";
system.stateVersion = "24.05";
}
];
};
packages = (import ./default.nix {
inherit pkgs nix-filter;
ddm = ddm.packages.${system}.default;
treeland-protocols = treeland-protocols.packages.${system}.default;
}) // {
qemu = self.nixosConfigurations.${system}.vm.config.system.build.vm;
};
treeland = packages.default;
packages = {
default = treeland;
qemu = self.nixosConfigurations.${system}.vm.config.system.build.vm;
};
apps.qemu = {
type = "app";
@ -175,27 +195,13 @@
devShells.default = pkgs.mkShell {
packages = with pkgs; [
# For submodule waylib and qwlroots
# For submodule build
libinput
wayland
wayland-protocols
wlr-protocols
vulkan-loader
xorg.libXdmcp
xorg.xcbutilerrors
seatd
wlroots_0_19
mesa
libdrm
vulkan-loader
seatd
];
inputsFrom = [
self.packages.${system}.treeland.override {
#It's submodule, prevent infinite loop calls
waylib = null;
qwlroot = null;
}
self.packages.${system}.default
];
shellHook =
@ -206,8 +212,8 @@
''
#export QT_LOGGING_RULES="*.debug=true;qt.*.debug=false"
#export WAYLAND_DEBUG=1
export QT_PLUGIN_PATH=${makeQtpluginPath (with pkgs.qt6; [ qtbase qtdeclarative qtimageformats qtwayland qtsvg ])}
export QML2_IMPORT_PATH=${makeQmlpluginPath (with pkgs; with qt6; [ qtdeclarative deepin.dtk6declarative ] )}
export QT_PLUGIN_PATH=${makeQtpluginPath (with pkgs.qt6; [ qtbase qtdeclarative qtquick3d qtimageformats qtwayland qt5compat qtsvg ])}
export QML2_IMPORT_PATH=${makeQmlpluginPath (with pkgs; with qt6; [ qtdeclarative qtquick3d qt5compat deepin.dtk6declarative ] )}
export QML_IMPORT_PATH=$QML2_IMPORT_PATH
'';
};

View File

@ -1,5 +1,6 @@
add_subdirectory(cmake)
add_subdirectory(dbus)
add_subdirectory(dconfig)
add_subdirectory(systemd)
add_subdirectory(wayland-sessions)
add_subdirectory(cmake)
add_subdirectory(portal)

View File

@ -1,11 +1,8 @@
include(CMakePackageConfigHelpers)
configure_file(TreeLandProtocolsConfig.cmake.in TreeLandProtocolsConfig.cmake)
configure_file(treeland-protocols.pc.in treeland-protocols.pc)
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/TreelandConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/TreelandConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/treeland
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/TreeLandProtocolsConfig.cmake
DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/TreeLandProtocols/)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/TreelandConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/treeland
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/treeland-protocols.pc
DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig)

View File

@ -0,0 +1 @@
set(TREELAND_PROTOCOLS_DATA_DIR @CMAKE_INSTALL_FULL_DATAROOTDIR@/treeland-protocols/)

View File

@ -1,3 +0,0 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/TreelandTargets.cmake")

View File

@ -0,0 +1,7 @@
prefix=@CMAKE_INSTALL_PREFIX@
datarootdir=@CMAKE_INSTALL_FULL_DATAROOTDIR@
pkgdatadir=${pc_sysrootdir}${datarootdir}/treeland-protocols/
Name: TreeLand Protocols
Description: TreeLand protocol files
Version: @PROJECT_VERSION@

View File

@ -11,7 +11,7 @@
"description": "Allow show context on lock screen",
"description[zh_CN]": "允许在锁屏界面上显示内容",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"lostScreen": {
"value": "MoveToPrimary",
@ -22,10 +22,10 @@
"description": "Behaivor when lost screen, allow value: MoveToPrimary、Minimize",
"description[zh_CN]": "丢失屏幕的行为可选值为MoveToPrimary、Minimize",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"font": {
"value": "Source Han Sans SC",
"value": "",
"serial": 0,
"flags": ["user-public"],
"name": "Font",
@ -33,10 +33,10 @@
"description": "Font Family",
"description[zh_CN]": "字体",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"monoFont": {
"value": "Noto Mono",
"value": "",
"serial": 0,
"flags": ["user-public"],
"name": "Mono Font",
@ -44,10 +44,10 @@
"description": "Mono Font Family",
"description[zh_CN]": "等宽字体",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"fontSize": {
"value": 105,
"value": 14,
"serial": 0,
"flags": ["user-public"],
"name": "Font Size",
@ -55,10 +55,10 @@
"description": "Font Size",
"description[zh_CN]": "字体大小",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"windowRadius": {
"value": 12,
"value": 18,
"serial": 0,
"flags": ["user-public"],
"name": "Round Corner Radius",
@ -66,7 +66,7 @@
"description": "Window Corner Round Radius",
"description[zh_CN]": "设置窗口圆角大小",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"preferDark": {
"value": false,
@ -77,7 +77,7 @@
"description": "Color scheme is prefer dark",
"description[zh_CN]": "颜色方案是否倾向暗色",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"themeName": {
"value": "",
@ -88,10 +88,10 @@
"description": "Theme Name",
"description[zh_CN]": "主题名称",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"iconThemeName": {
"value": "nirvana",
"value": "bloom",
"serial": 0,
"flags": ["user-public"],
"name": "Icon Theme Name",
@ -99,7 +99,7 @@
"description": "Icon Theme Name",
"description[zh_CN]": "图标主题名称",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"cursorThemeName": {
"value": "bloom",
@ -110,7 +110,7 @@
"description": "Cursor Theme Name",
"description[zh_CN]": "光标主题名称",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"cursorSize": {
"value": 24,
@ -121,7 +121,7 @@
"description": "Cursor Size",
"description[zh_CN]": "光标大小",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"cursorBlink": {
"value": true,
@ -132,7 +132,7 @@
"description": "Whether the cursor should blink",
"description[zh_CN]": "光标是否应闪烁",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"cursorBlinkTime": {
"value": 1200,
@ -143,7 +143,7 @@
"description": "Length of the cursor blink cycle, in milleseconds",
"description[zh_CN]": "光标闪烁周期的长度,以千秒为单位",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"doubleClickTime": {
"value": 250,
@ -154,7 +154,7 @@
"description": "Maximum time allowed between two clicks for them to be considered a double click (in milliseconds)",
"description[zh_CN]": "两次单击之间允许被视为双击的最长时间(以毫秒为单位)",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"doubleClickDistance": {
"value": 5,
@ -165,7 +165,7 @@
"description": "Maximum distance allowed between two clicks for them to be considered a double click (in pixels)",
"description[zh_CN]": "两次单击之间允许被视为双击的最大距离(以像素为单位)",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"dndDragThreshold": {
"value": 8,
@ -176,7 +176,7 @@
"description": "Number of pixels the cursor can move before dragging",
"description[zh_CN]": "拖动之前光标可以移动的像素数",
"permissions": "readwrite",
"visibility": "public"
"visibility": "private"
},
"maxWorkspace": {
"value": 6,
@ -190,7 +190,7 @@
"visibility": "private"
},
"numWorkspace": {
"value": 2,
"value": 4,
"serial": 0,
"flags": ["user-public"],
"name": "Number of workspaces",
@ -200,7 +200,7 @@
"permissions": "readwrite",
"visibility": "private"
},
"currentWorkspace": {
"currentWorkspace": {
"value": 0,
"serial": 0,
"flags": ["user-public"],
@ -210,249 +210,6 @@
"description[zh_CN]": "当前工作区索引",
"permissions": "readwrite",
"visibility": "private"
},
"forceSoftwareCursor": {
"value": false,
"serial": 0,
"flags": ["global"],
"name": "Force Software Cursor",
"name[zh_CN]": "强制软光标渲染",
"description": "Force software cursor rendering",
"description[zh_CN]": "强制使用软光标进行渲染",
"permissions": "readwrite",
"visibility": "public"
},
"activeColor": {
"value": "#1F6EE7",
"serial": 0,
"flags": ["global"],
"name": "Global Window Active Color",
"name[zh_CN]": "全局窗口活动色",
"description": "Set window active color",
"description[zh_CN]": "设置窗口活动色",
"permissions": "readwrite",
"visibility": "public"
},
"windowOpacity": {
"value": 40,
"serial": 0,
"flags": ["global"],
"name": "Global Window Opacity",
"name[zh_CN]": "全局窗口不透明度",
"description": "Set all window opacity",
"description[zh_CN]": "设置所有窗口的不透明度",
"permissions": "readwrite",
"visibility": "public"
},
"windowThemeType": {
"value": 0,
"serial": 0,
"flags": ["global"],
"name": "Global Window Theme Type",
"name[zh_CN]": "全局窗口主题类型",
"description": "Set all window theme type",
"description[zh_CN]": "设置所有窗口的主题类型",
"permissions": "readwrite",
"visibility": "public"
},
"windowTitlebarHeight": {
"value": 40,
"serial": 0,
"flags": ["global"],
"name": "Global Window titlebar height",
"name[zh_CN]": "全局标题栏高度",
"description": "Set all window default titlebar height",
"description[zh_CN]": "设置所有窗口默认的标题栏高度",
"permissions": "readwrite",
"visibility": "public"
},
"defaultBackground": {
"value": "/usr/share/backgrounds/default_background.jpg",
"serial": 0,
"flags": ["global"],
"name": "Default background",
"name[zh_CN]": "默认壁纸",
"description": "Set the default displayed wallpaper, when no wallpaper is set",
"description[zh_CN]": "当没有设置壁纸时,设置默认显示的壁纸",
"permissions": "readwrite",
"visibility": "public"
},
"workspaceThumbHeight": {
"value": 144,
"serial": 0,
"flags": ["global"],
"name": "Workspace thumbnail height",
"name[zh_CN]": "工作区缩略图高度",
"description": "Workspace thumbnail height",
"description[zh_CN]": "工作区缩略图高度",
"permissions": "readonly",
"visibility": "private"
},
"workspaceThumbMargin": {
"value": 20,
"serial": 0,
"flags": ["global"],
"name": "Workspace thumbnail margin",
"name[zh_CN]": "工作区缩略图边距",
"description": "Workspace thumbnail margin",
"description[zh_CN]": "工作区缩略图边距",
"permissions": "readonly",
"visibility": "private"
},
"workspaceThumbCornerRadius": {
"value": 8,
"serial": 0,
"flags": ["global"],
"name": "Workspace thumbnail corner radius",
"name[zh_CN]": "工作区缩略图圆角弧度",
"description": "Workspace thumbnail corner radius",
"description[zh_CN]": "工作区缩略图圆角弧度",
"permissions": "readonly",
"visibility": "private"
},
"highlightBorderWidth": {
"value": 4,
"serial": 0,
"flags": ["global"],
"name": "Highlight border width",
"name[zh_CN]": "高亮边框宽度",
"description": "Highlight border width",
"description[zh_CN]": "高亮边框宽度",
"permissions": "readonly",
"visibility": "private"
},
"minMultitaskviewSurfaceHeight": {
"value": 232,
"serial": 0,
"flags": ["global"],
"name": "Multitask view surface minimal height",
"name[zh_CN]": "多任务视图表面最小高度",
"description": "Multitask view surface minimal height",
"description[zh_CN]": "多任务视图表面最小高度",
"permissions": "readonly",
"visibility": "private"
},
"titleBoxCornerRadius": {
"value": 8,
"serial": 0,
"flags": ["global"],
"name": "Title box corner radius",
"name[zh_CN]": "标题框圆角弧度",
"description": "Title box corner radius",
"description[zh_CN]": "标题框圆角弧度",
"permissions": "readonly",
"visibility": "private"
},
"normalWindowHeight": {
"value": 720,
"serial": 0,
"flags": ["global"],
"name": "Normal window height",
"name[zh_CN]": "正常窗口高度",
"description": "Normal window height",
"description[zh_CN]": "正常窗口高度",
"permissions": "readonly",
"visibility": "private"
},
"windowHeightStep": {
"value": 15,
"serial": 0,
"flags": ["global"],
"name": "Window height step",
"name[zh_CN]": "窗口高度梯度",
"description": "Window height step",
"description[zh_CN]": "窗口高度梯度",
"permissions": "readonly",
"visibility": "private"
},
"multitaskviewPaddingOpacity": {
"value": 0.1,
"serial": 0,
"flags": ["global"],
"name": "Multitaskview padding opacity",
"name[zh_CN]": "多任务视图内边距不透明度",
"description": "Multitask view padding opacity",
"description[zh_CN]": "多任务视图内边距不透明度",
"permissions": "readonly",
"visibility": "private"
},
"multitaskviewAnimationDuration": {
"value": 300,
"serial": 0,
"flags": ["global"],
"name": "Multitaskview animation duration",
"name[zh_CN]": "多任务视图动画时长",
"description": "Multitaskview animation duration",
"description[zh_CN]": "多任务视图动画时长",
"permissions": "readonly",
"visibility": "private"
},
"multitaskviewEasingCurveType": {
"value": 22,
"serial": 0,
"flags": ["global"],
"name": "Multitaskview easing curve type",
"name[zh_CN]": "多任务视图缓动曲线类型",
"description": "Multitaskview easing curve type, enumerate value of QEasingCurve::Type",
"description[zh_CN]": "多任务视图缓动曲线类型其值为QEasingCurve::Type类型的枚举值",
"permissions": "readonly",
"visibility": "private"
},
"multitaskviewTopContentMargin": {
"value": 40,
"serial": 0,
"flags": ["global"],
"name": "Multitaskview top content margin",
"name[zh_CN]": "多任务视图内容顶边距",
"description": "Multitaskview top content margin",
"description[zh_CN]": "多任务视图内容顶边距",
"permissions": "readonly",
"visibility": "private"
},
"multitaskviewBottomContentMargin": {
"value": 60,
"serial": 0,
"flags": ["global"],
"name": "Multitaskview bottom content margin",
"name[zh_CN]": "多任务视图内容底边距",
"description": "Multitaskview bottom content margin",
"description[zh_CN]": "多任务视图内容底边距",
"permissions": "readonly",
"visibility": "private"
},
"multitaskviewHorizontalMargin": {
"value": 20,
"serial": 0,
"flags": ["global"],
"name": "Multitaskview horizontal margin",
"name[zh_CN]": "多任务视图横向边距",
"description": "Multitaskview horizontal margin",
"description[zh_CN]": "多任务视图横向边距",
"permissions": "readonly",
"visibility": "private"
},
"multitaskviewCellPadding": {
"value": 12,
"serial": 0,
"flags": ["global"],
"name": "Multitaskview cell padding",
"name[zh_CN]": "多任务视图单元格间距",
"description": "Multitaskview cell padding",
"description[zh_CN]": "多任务视图单元格间距",
"permissions": "readonly",
"visibility": "private"
},
"multitaskviewLoadFactor": {
"value": 0.6,
"serial": 0,
"flags": ["global"],
"name": "Multitaskview load factor",
"name[zh_CN]": "多任务视图加载因子",
"description": "Multitaskview load factor",
"description[zh_CN]": "多任务视图加载因子",
"permissions": "readonly",
"visibility": "private"
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
misc/icons/login_sleep.dci Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,18 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.deepin.DisplayManager">
<method name="AuthInfo">
<arg type="s" name="auth socket" direction="out">
</arg>
</method>
<signal name="AuthInfoChanged">
</signal>
<method name="LastActivatedUser">
<arg type="s" name="last activated user" direction="out">
</arg>
</method>
<signal name="LastActivatedUserChanged">
</signal>
</interface>
</node>

View File

@ -1,220 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.Manager">
<property name="NAutoVTs" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="KillOnlyUsers" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="KillExcludeUsers" type="as" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="KillUserProcesses" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="IdleHint" type="b" access="read">
</property>
<property name="IdleSinceHint" type="t" access="read">
</property>
<property name="IdleSinceHintMonotonic" type="t" access="read">
</property>
<property name="BlockInhibited" type="s" access="read">
</property>
<property name="DelayInhibited" type="s" access="read">
</property>
<property name="InhibitDelayMaxUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandlePowerKey" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleSuspendKey" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleHibernateKey" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="HandleLidSwitch" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="IdleAction" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="IdleActionUSec" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="PreparingForShutdown" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="PreparingForSleep" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<method name="GetSession">
<arg type="s" direction="in"/>
<arg type="o" direction="out"/>
</method>
<method name="GetSessionByPID">
<arg type="u" direction="in"/>
<arg type="o" direction="out"/>
</method>
<method name="GetUser">
<arg type="u" direction="in"/>
<arg type="o" direction="out"/>
</method>
<method name="GetUserByPID">
<arg type="u" direction="in"/>
<arg type="o" direction="out"/>
</method>
<method name="GetSeat">
<arg type="s" direction="in"/>
<arg type="o" direction="out"/>
</method>
<method name="ListSessions">
<arg type="a(susso)" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="SessionInfoList"/>
</method>
<method name="ListUsers">
<arg type="a(uso)" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="UserInfoList"/>
</method>
<method name="ListSeats">
<arg type="a(so)" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="NamedSeatPathList"/>
</method>
<method name="ListInhibitors">
<arg type="a(ssssuu)" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="InhibitorList"/>
</method>
<method name="ReleaseSession">
<arg type="s" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="ActivateSession">
<arg type="s" direction="in"/>
</method>
<method name="ActivateSessionOnSeat">
<arg type="s" direction="in"/>
<arg type="s" direction="in"/>
</method>
<method name="LockSession">
<arg type="s" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="UnlockSession">
<arg type="s" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="LockSessions">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="UnlockSessions">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="KillSession">
<arg type="s" direction="in"/>
<arg type="s" direction="in"/>
<arg type="i" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="KillUser">
<arg type="u" direction="in"/>
<arg type="i" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="TerminateSession">
<arg type="s" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="TerminateUser">
<arg type="u" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="TerminateSeat">
<arg type="s" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="SetUserLinger">
<arg type="u" direction="in"/>
<arg type="b" direction="in"/>
<arg type="b" direction="in"/>
</method>
<method name="AttachDevice">
<arg type="s" direction="in"/>
<arg type="s" direction="in"/>
<arg type="b" direction="in"/>
</method>
<method name="FlushDevices">
<arg type="b" direction="in"/>
</method>
<method name="PowerOff">
<arg type="b" direction="in"/>
</method>
<method name="Reboot">
<arg type="b" direction="in"/>
</method>
<method name="Suspend">
<arg type="b" direction="in"/>
</method>
<method name="Hibernate">
<arg type="b" direction="in"/>
</method>
<method name="HybridSleep">
<arg type="b" direction="in"/>
</method>
<method name="CanPowerOff">
<arg type="s" direction="out"/>
</method>
<method name="CanReboot">
<arg type="s" direction="out"/>
</method>
<method name="CanSuspend">
<arg type="s" direction="out"/>
</method>
<method name="CanHibernate">
<arg type="s" direction="out"/>
</method>
<method name="CanHybridSleep">
<arg type="s" direction="out"/>
</method>
<method name="Inhibit">
<arg type="s" direction="in"/>
<arg type="s" direction="in"/>
<arg type="s" direction="in"/>
<arg type="s" direction="in"/>
<arg type="h" direction="out"/>
</method>
<signal name="SessionNew">
<arg type="s"/>
<arg type="o"/>
</signal>
<signal name="SessionRemoved">
<arg type="s"/>
<arg type="o"/>
</signal>
<signal name="UserNew">
<arg type="u"/>
<arg type="o"/>
</signal>
<signal name="UserRemoved">
<arg type="u"/>
<arg type="o"/>
</signal>
<signal name="SeatNew">
<arg type="s"/>
<arg type="o"/>
</signal>
<signal name="SeatRemoved">
<arg type="s"/>
<arg type="o"/>
</signal>
<signal name="PrepareForShutdown">
<arg type="b"/>
</signal>
<signal name="PrepareForSleep">
<arg type="b"/>
</signal>
</interface>
</node>

View File

@ -1,43 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.Seat">
<property name="Id" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="ActiveSession" type="(so)" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="NamedSessionPath"/>
</property>
<property name="CanMultiSession" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="CanTTY" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="CanGraphical" type="b" access="read">
</property>
<property name="Sessions" type="a(so)" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="QList&lt;NamedSessionPath&gt;"/>
</property>
<property name="IdleHint" type="b" access="read">
</property>
<property name="IdleSinceHint" type="t" access="read">
</property>
<property name="IdleSinceHintMonotonic" type="t" access="read">
</property>
<method name="Terminate">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="ActivateSession">
<arg type="s" direction="in"/>
</method>
<method name="SwitchTo">
<arg type="u" direction="in"/>
</method>
<method name="SwitchToNext">
</method>
<method name="SwitchToPrevious">
</method>
</interface>
</node>

View File

@ -1,132 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.Session">
<property name="Id" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="User" type="(uo)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
<annotation name="org.qtproject.QtDBus.QtTypeName" value="NamedUserPath"/>
</property>
<property name="Name" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Timestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="TimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="VTNr" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Seat" type="(so)" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
<annotation name="org.qtproject.QtDBus.QtTypeName" value="NamedSeatPath"/>
</property>
<property name="TTY" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Display" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Remote" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="RemoteHost" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="RemoteUser" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Service" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Desktop" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Scope" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Leader" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Audit" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Type" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Class" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
<annotation name="org.qtproject.QtDBus.PropertyGetter" value="className"/>
</property>
<property name="Active" type="b" access="read">
</property>
<property name="State" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="IdleHint" type="b" access="read">
</property>
<property name="IdleSinceHint" type="t" access="read">
</property>
<property name="IdleSinceHintMonotonic" type="t" access="read">
</property>
<method name="Terminate">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="Activate">
</method>
<method name="Lock">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
<annotation name="org.qtproject.QtDBus.MethodName" value="requestLock"/>
</method>
<method name="Unlock">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
<annotation name="org.qtproject.QtDBus.MethodName" value="requestUnlock"/>
</method>
<method name="SetIdleHint">
<arg type="b" direction="in"/>
</method>
<method name="Kill">
<arg type="s" direction="in"/>
<arg type="i" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="TakeControl">
<arg type="b" direction="in"/>
</method>
<method name="ReleaseControl">
</method>
<method name="TakeDevice">
<arg type="u" direction="in"/>
<arg type="u" direction="in"/>
<arg type="h" direction="out"/>
<arg type="b" direction="out"/>
</method>
<method name="ReleaseDevice">
<arg type="u" direction="in"/>
<arg type="u" direction="in"/>
</method>
<method name="PauseDeviceComplete">
<arg type="u" direction="in"/>
<arg type="u" direction="in"/>
</method>
<signal name="PauseDevice">
<arg type="u"/>
<arg type="u"/>
<arg type="s"/>
</signal>
<signal name="ResumeDevice">
<arg type="u"/>
<arg type="u"/>
<arg type="h"/>
</signal>
<signal name="Lock">
</signal>
<signal name="Unlock">
</signal>
</interface>
</node>

View File

@ -1,56 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.login1.User">
<property name="UID" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="GID" type="u" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Name" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Timestamp" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="TimestampMonotonic" type="t" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="RuntimePath" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Service" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Slice" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
</property>
<property name="Display" type="(so)" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="NamedSessionPath"/>
</property>
<property name="State" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<property name="Sessions" type="a(so)" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName" value="QList&lt;NamedSessionPath&gt;"/>
</property>
<property name="IdleHint" type="b" access="read">
</property>
<property name="IdleSinceHint" type="t" access="read">
</property>
<property name="IdleSinceHintMonotonic" type="t" access="read">
</property>
<property name="Linger" type="b" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
<method name="Terminate">
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
<method name="Kill">
<arg type="i" direction="in"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</method>
</interface>
</node>

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