diff --git a/.gitignore b/.gitignore index 7f34edf..da01e77 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,7 @@ CMakeLists.txt.user #ccls .ccls-cache + +# emacs +*~ +#*# \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c0bf12..f6acc77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,6 @@ include(FeatureSummary) # Options option(BUILD_MAN_PAGES "Build man pages" OFF) option(ENABLE_JOURNALD "Enable logging to journald" ON) -option(NO_SYSTEMD "Disable systemd support" OFF) -option(USE_ELOGIND "Use elogind instead of logind" OFF) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -67,15 +65,12 @@ find_package(PkgConfig) # PAM find_package(PAM REQUIRED) +# Systemd +pkg_check_modules(Systemd REQUIRED systemd) + # XAU pkg_check_modules(LIBXAU REQUIRED "xau") -# XCB -find_package(XCB REQUIRED) - -# XKB -find_package(XKB REQUIRED) - # TreelandProtocols find_package(TreelandProtocols 0.5.0 REQUIRED) @@ -90,83 +85,39 @@ if ("${ECM_VERSION}" VERSION_LESS "1.7.0") add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") endif() -# systemd -if(NOT NO_SYSTEMD AND NOT USE_ELOGIND) - pkg_check_modules(SYSTEMD "systemd") -endif() +add_definitions(-DHAVE_SYSTEMD) +set(CMAKE_AUTOMOC_MOC_OPTIONS -DHAVE_SYSTEMD) -if(SYSTEMD_FOUND) - add_definitions(-DHAVE_SYSTEMD) - set(CMAKE_AUTOMOC_MOC_OPTIONS -DHAVE_SYSTEMD) +# libsystemd-journal was merged into libsystemd in 209 +pkg_check_modules(JOURNALD "libsystemd") - # libsystemd-journal was merged into libsystemd in 209 - if(${SYSTEMD_VERSION} VERSION_LESS 209) - pkg_check_modules(JOURNALD "libsystemd-journal") +if(ENABLE_JOURNALD) + if(JOURNALD_FOUND) + add_definitions(-DHAVE_JOURNALD) + set(CMAKE_AUTOMOC_MOC_OPTIONS -DHAVE_JOURNALD) else() - pkg_check_modules(JOURNALD "libsystemd") - endif() - - if(ENABLE_JOURNALD) - if(JOURNALD_FOUND) - add_definitions(-DHAVE_JOURNALD) - set(CMAKE_AUTOMOC_MOC_OPTIONS -DHAVE_JOURNALD) - else() - message(WARNING "Disable journald support for lack of libsystemd-journal") - endif() - endif() - - if (NOT DEFINED SYSTEMD_SYSTEM_UNIT_DIR) - pkg_get_variable(SYSTEMD_SYSTEM_UNIT_DIR systemd systemdsystemunitdir) - endif() - - if (NOT DEFINED SYSTEMD_SYSUSERS_DIR) - pkg_get_variable(SYSTEMD_SYSUSERS_DIR systemd sysusersdir) + message(WARNING "Disable journald support for lack of libsystemd-journal") endif() +endif() - if (NOT DEFINED SYSTEMD_TMPFILES_DIR) - pkg_get_variable(SYSTEMD_TMPFILES_DIR systemd tmpfilesdir) - endif() +if (NOT DEFINED SYSTEMD_SYSTEM_UNIT_DIR) + pkg_get_variable(SYSTEMD_SYSTEM_UNIT_DIR systemd systemdsystemunitdir) +endif() - set(HALT_COMMAND "/usr/bin/systemctl poweroff") - set(REBOOT_COMMAND "/usr/bin/systemctl reboot") -else() - set(SYSTEMD_FOUND 0) +if (NOT DEFINED SYSTEMD_SYSUSERS_DIR) + pkg_get_variable(SYSTEMD_SYSUSERS_DIR systemd sysusersdir) endif() -add_feature_info("systemd" SYSTEMD_FOUND "systemd support") -add_feature_info("journald" JOURNALD_FOUND "journald support") -# elogind -if(NO_SYSTEMD AND USE_ELOGIND) - pkg_check_modules(ELOGIND "libelogind") +if (NOT DEFINED SYSTEMD_TMPFILES_DIR) + pkg_get_variable(SYSTEMD_TMPFILES_DIR systemd tmpfilesdir) endif() -if(ELOGIND_FOUND) - add_definitions(-DHAVE_ELOGIND) - set(CMAKE_AUTOMOC_MOC_OPTIONS -DHAVE_ELOGIND) +set(HALT_COMMAND "/usr/bin/systemctl poweroff") +set(REBOOT_COMMAND "/usr/bin/systemctl reboot") - set(HALT_COMMAND "/usr/bin/loginctl poweroff") - set(REBOOT_COMMAND "/usr/bin/loginctl reboot") -endif() -add_feature_info("elogind" ELOGIND_FOUND "elogind support") - -# Default behaviour if neither systemd nor elogind is used -if (NOT ELOGIND_FOUND AND NOT SYSTEMD_FOUND) - # Set the VT on which ddm will normally appear, and the - # commands for shutdown and reboot. On FreeBSD, there are - # normally more getty's running than on Linux. - if("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") - set(HALT_COMMAND "/sbin/shutdown -p now") - else() - set(HALT_COMMAND "/sbin/shutdown -h -P now") - endif() - set(REBOOT_COMMAND "/sbin/shutdown -r now") -endif() +add_feature_info("journald" JOURNALD_FOUND "journald support") -if (SYSTEMD_FOUND) - set(RUNTIME_DIR_DEFAULT "/run/ddm") -else() - set(RUNTIME_DIR_DEFAULT "${CMAKE_INSTALL_LOCALSTATEDIR}/run/ddm") -endif() +set(RUNTIME_DIR_DEFAULT "/run/ddm") # Set constants set(DATA_INSTALL_DIR "${CMAKE_INSTALL_FULL_DATADIR}/ddm" CACHE PATH "System application data install directory") @@ -224,9 +175,6 @@ add_subdirectory(data) add_subdirectory(services) add_subdirectory(src) -# enable_testing() -# add_subdirectory(test) - # Display feature summary feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/REUSE.toml b/REUSE.toml index 5d004f3..9049026 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -69,7 +69,7 @@ SPDX-FileCopyrightText = "None" SPDX-License-Identifier = "GPL-2.0-or-later" [[annotations]] -path = ["releng/prepare-relnotes", "src/daemon/Auth.cpp", "src/daemon/Auth.h", "src/common/ConfigReader.cpp", "src/common/ConfigReader.h", "src/common/Configuration.cpp", "src/common/Configuration.h", "src/common/MessageHandler.h", "src/common/Messages.h", "src/common/SafeDataStream.cpp", "src/common/SafeDataStream.h", "src/common/Session.cpp", "src/common/Session.h", "src/common/SignalHandler.cpp", "src/common/SignalHandler.h", "src/common/SocketWriter.cpp", "src/common/SocketWriter.h", "src/common/ThemeConfig.cpp", "src/common/ThemeConfig.h", "src/common/ThemeMetadata.cpp", "src/common/ThemeMetadata.h", "src/common/VirtualTerminal.cpp", "src/common/VirtualTerminal.h", "src/common/XAuth.cpp", "src/common/XAuth.h", "src/daemon/DaemonApp.cpp", "src/daemon/DaemonApp.h", "src/daemon/Display.cpp", "src/daemon/Display.h", "src/daemon/DisplayManager.cpp", "src/daemon/DisplayManager.h", "src/daemon/PowerManager.cpp", "src/daemon/PowerManager.h", "src/daemon/Seat.cpp", "src/daemon/Seat.h", "src/daemon/SeatManager.cpp", "src/daemon/SeatManager.h", "src/daemon/SocketServer.cpp", "src/daemon/SocketServer.h", "src/daemon/TreelandConnector.cpp", "src/daemon/TreelandConnector.h", "src/daemon/Utils.h", "src/daemon/XorgDisplayServer.cpp", "src/daemon/XorgDisplayServer.h", "src/greeter/GreeterApp.h", "src/greeter/GreeterProxy.cpp", "src/greeter/GreeterProxy.h", "src/greeter/SessionModel.cpp", "src/greeter/SessionModel.h", "src/greeter/UserModel.cpp", "src/greeter/UserModel.h", "src/daemon/Pam.cpp", "src/daemon/Pam.h", "src/daemon/UserSession.cpp", "src/daemon/UserSession.h", "src/common/LogindDBusTypes.cpp", "src/common/LogindDBusTypes.h", "src/greeter/GreeterApp.cpp"] +path = ["releng/prepare-relnotes", "src/daemon/Auth.cpp", "src/daemon/Auth.h", "src/common/ConfigReader.cpp", "src/common/ConfigReader.h", "src/common/Configuration.cpp", "src/common/Configuration.h", "src/common/MessageHandler.h", "src/common/Messages.h", "src/common/Session.cpp", "src/common/Session.h", "src/common/SignalHandler.cpp", "src/common/SignalHandler.h", "src/common/SocketWriter.cpp", "src/common/SocketWriter.h", "src/common/VirtualTerminal.cpp", "src/common/VirtualTerminal.h", "src/common/XAuth.cpp", "src/common/XAuth.h", "src/daemon/DaemonApp.cpp", "src/daemon/DaemonApp.h", "src/daemon/Display.cpp", "src/daemon/Display.h", "src/daemon/DisplayManager.cpp", "src/daemon/DisplayManager.h", "src/daemon/PowerManager.cpp", "src/daemon/PowerManager.h", "src/daemon/SeatManager.cpp", "src/daemon/SeatManager.h", "src/daemon/SocketServer.cpp", "src/daemon/SocketServer.h", "src/daemon/TreelandConnector.cpp", "src/daemon/TreelandConnector.h", "src/daemon/Utils.h", "src/daemon/XorgDisplayServer.cpp", "src/daemon/XorgDisplayServer.h", "src/greeter/GreeterApp.h", "src/greeter/GreeterProxy.cpp", "src/greeter/GreeterProxy.h", "src/greeter/SessionModel.cpp", "src/greeter/SessionModel.h", "src/greeter/UserModel.cpp", "src/greeter/UserModel.h", "src/daemon/Pam.cpp", "src/daemon/Pam.h", "src/daemon/UserSession.cpp", "src/daemon/UserSession.h", "src/common/LogindDBusTypes.cpp", "src/common/LogindDBusTypes.h", "src/greeter/GreeterApp.cpp"] precedence = "aggregate" SPDX-FileCopyrightText = "None" SPDX-License-Identifier = "GPL-2.0-or-later" diff --git a/cmake/FindXCB.cmake b/cmake/FindXCB.cmake deleted file mode 100644 index 95703ef..0000000 --- a/cmake/FindXCB.cmake +++ /dev/null @@ -1,54 +0,0 @@ -# - Try to find libxcb -# Once done this will define -# -# LIBXCB_FOUND - system has libxcb -# LIBXCB_LIBRARIES - Link these to use libxcb -# LIBXCB_INCLUDE_DIR - the libxcb include dir -# LIBXCB_DEFINITIONS - compiler switches required for using libxcb - -# Copyright (c) 2008 Helio Chissini de Castro, -# Copyright (c) 2007, Matthias Kretz, -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. The name of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -IF (NOT WIN32) - IF (LIBXCB_INCLUDE_DIR AND LIBXCB_LIBRARIES) - # in cache already - SET(XCB_FIND_QUIETLY TRUE) - ENDIF (LIBXCB_INCLUDE_DIR AND LIBXCB_LIBRARIES) - - FIND_PACKAGE(PkgConfig) - PKG_CHECK_MODULES(PKG_XCB xcb) - - SET(LIBXCB_DEFINITIONS ${PKG_XCB_CFLAGS}) - - FIND_PATH(LIBXCB_INCLUDE_DIR xcb/xcb.h ${PKG_XCB_INCLUDE_DIRS}) - FIND_LIBRARY(LIBXCB_LIBRARIES NAMES xcb libxcb PATHS ${PKG_XCB_LIBRARY_DIRS}) - - include(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(XCB DEFAULT_MSG LIBXCB_LIBRARIES LIBXCB_INCLUDE_DIR) - - MARK_AS_ADVANCED(LIBXCB_INCLUDE_DIR LIBXCB_LIBRARIES XCBPROC_EXECUTABLE) -ENDIF (NOT WIN32) diff --git a/cmake/FindXKB.cmake b/cmake/FindXKB.cmake deleted file mode 100644 index 97bd45c..0000000 --- a/cmake/FindXKB.cmake +++ /dev/null @@ -1,135 +0,0 @@ -# - Try to find libxcb -# Once done this will define -# -# LIBXKB_FOUND - system has libxcb -# LIBXKB_LIBRARIES - Link these to use libxcb-xkb -# LIBXKB_INCLUDE_DIR - the libxcb-xkb include dir -# LIBXKB_DEFINITIONS - compiler switches required for using libxcb - -# Copyright (c) 2013, Abdurrahman AVCI, -# Copyright (c) 2008, Helio Chissini de Castro, -# Copyright (c) 2007, Matthias Kretz, -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. The name of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -IF (NOT WIN32) - IF (LIBXKB_INCLUDE_DIR AND LIBXKB_LIBRARIES) - # in cache already - SET(XKB_FIND_QUIETLY TRUE) - ENDIF (LIBXKB_INCLUDE_DIR AND LIBXKB_LIBRARIES) - - # use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls - FIND_PACKAGE(PkgConfig) - PKG_CHECK_MODULES(PKG_XKB xcb-xkb) - - SET(LIBXKB_DEFINITIONS ${PKG_XKB_CFLAGS}) - - FIND_PATH(LIBXKB_INCLUDE_DIR xcb/xkb.h ${PKG_XKB_INCLUDE_DIRS}) - - FIND_LIBRARY(LIBXKB_LIBRARIES NAMES xcb-xkb libxcb-xkb PATHS ${PKG_XKB_LIBRARY_DIRS}) - - include(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(XKB DEFAULT_MSG LIBXKB_LIBRARIES LIBXKB_INCLUDE_DIR) - - MARK_AS_ADVANCED(LIBXKB_INCLUDE_DIR LIBXKB_LIBRARIES) -ENDIF (NOT WIN32) - -#.rst: -# FindXKB -# ------- -# -# Try to find xkbcommon on a Unix system -# If found, this will define the following variables: -# -# ``XKB_FOUND`` -# True if XKB is available -# ``XKB_LIBRARIES`` -# Link these to use XKB -# ``XKB_INCLUDE_DIRS`` -# Include directory for XKB -# ``XKB_DEFINITIONS`` -# Compiler flags for using XKB -# -# Additionally, the following imported targets will be defined: -# -# ``XKB::XKB`` -# The XKB library - -if(NOT WIN32) - # Use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls - find_package(PkgConfig) - pkg_check_modules(PKG_XKB QUIET xkbcommon) - - set(XKB_DEFINITIONS ${PKG_XKB_CFLAGS_OTHER}) - - find_path(XKB_INCLUDE_DIR - NAMES - xkbcommon/xkbcommon.h - HINTS - ${PKG_XKB_INCLUDE_DIRS} - ) - find_library(XKB_LIBRARY - NAMES - xkbcommon - HINTS - ${PKG_XKB_LIBRARY_DIRS} - ) - - set(XKB_LIBRARIES ${XKB_LIBRARY}) - set(XKB_INCLUDE_DIRS ${XKB_INCLUDE_DIR}) - set(XKB_VERSION ${PKG_XKB_VERSION}) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(XKB - FOUND_VAR - XKB_FOUND - REQUIRED_VARS - XKB_LIBRARY - XKB_INCLUDE_DIR - VERSION_VAR - XKB_VERSION - ) - - if(XKB_FOUND AND NOT TARGET XKB::XKB) - add_library(XKB::XKB UNKNOWN IMPORTED) - set_target_properties(XKB::XKB PROPERTIES - IMPORTED_LOCATION "${XKB_LIBRARY}" - INTERFACE_COMPILE_OPTIONS "${XKB_DEFINITIONS}" - INTERFACE_INCLUDE_DIRECTORIES "${XKB_INCLUDE_DIR}" - ) - endif() - -else() - message(STATUS "FindXKB.cmake cannot find XKB on Windows systems.") - set(XKB_FOUND FALSE) -endif() - -include(FeatureSummary) -set_package_properties(XKB PROPERTIES - URL "https://xkbcommon.org" - DESCRIPTION "XKB API common to servers and clients" -) \ No newline at end of file diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index f0c34cd..bef73ba 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -1,5 +1,3 @@ -install(DIRECTORY "flags" DESTINATION "${DATA_INSTALL_DIR}") - install(FILES "org.freedesktop.DisplayManager.conf" DESTINATION "${DBUS_CONFIG_DIR}" @@ -11,18 +9,6 @@ install(FILES DESTINATION "${DBUS_CONFIG_DIR}" ) -install(FILES - "faces/root.face.icon.png" - DESTINATION "${DATA_INSTALL_DIR}/faces" - RENAME "root.face.icon" -) - -install(FILES - "faces/default.face.icon.png" - DESTINATION "${DATA_INSTALL_DIR}/faces" - RENAME ".face.icon" -) - install(FILES "scripts/Xsession" "scripts/Xsetup" @@ -35,8 +21,6 @@ install(FILES WORLD_READ WORLD_EXECUTE ) -add_subdirectory(systemd) - if(BUILD_MAN_PAGES) add_subdirectory(man) endif() diff --git a/data/faces/README b/data/faces/README deleted file mode 100644 index 85479ad..0000000 --- a/data/faces/README +++ /dev/null @@ -1,2 +0,0 @@ -These are the default avatars. -They are installed to `.face.icon` and `root.face.icon`. See ../CMakeLists.txt. diff --git a/data/faces/default.face.icon.png b/data/faces/default.face.icon.png deleted file mode 100644 index cd7c4fd..0000000 Binary files a/data/faces/default.face.icon.png and /dev/null differ diff --git a/data/faces/root.face.icon.png b/data/faces/root.face.icon.png deleted file mode 100644 index 3084969..0000000 Binary files a/data/faces/root.face.icon.png and /dev/null differ diff --git a/data/flags/ae.png b/data/flags/ae.png deleted file mode 100644 index 1b77c21..0000000 Binary files a/data/flags/ae.png and /dev/null differ diff --git a/data/flags/am.png b/data/flags/am.png deleted file mode 100644 index 7b0d5f7..0000000 Binary files a/data/flags/am.png and /dev/null differ diff --git a/data/flags/ar.png b/data/flags/ar.png deleted file mode 100644 index 60167d9..0000000 Binary files a/data/flags/ar.png and /dev/null differ diff --git a/data/flags/at.png b/data/flags/at.png deleted file mode 100644 index 2af1e65..0000000 Binary files a/data/flags/at.png and /dev/null differ diff --git a/data/flags/az.png b/data/flags/az.png deleted file mode 100644 index 9d561fa..0000000 Binary files a/data/flags/az.png and /dev/null differ diff --git a/data/flags/bd.png b/data/flags/bd.png deleted file mode 100644 index b516bb7..0000000 Binary files a/data/flags/bd.png and /dev/null differ diff --git a/data/flags/be.png b/data/flags/be.png deleted file mode 100644 index 4252b21..0000000 Binary files a/data/flags/be.png and /dev/null differ diff --git a/data/flags/bg.png b/data/flags/bg.png deleted file mode 100644 index 7f929e6..0000000 Binary files a/data/flags/bg.png and /dev/null differ diff --git a/data/flags/bh.png b/data/flags/bh.png deleted file mode 100644 index a234dfe..0000000 Binary files a/data/flags/bh.png and /dev/null differ diff --git a/data/flags/br.png b/data/flags/br.png deleted file mode 100644 index ad76e45..0000000 Binary files a/data/flags/br.png and /dev/null differ diff --git a/data/flags/by.png b/data/flags/by.png deleted file mode 100644 index a40f445..0000000 Binary files a/data/flags/by.png and /dev/null differ diff --git a/data/flags/ca.png b/data/flags/ca.png deleted file mode 100644 index e24e3fd..0000000 Binary files a/data/flags/ca.png and /dev/null differ diff --git a/data/flags/ch.png b/data/flags/ch.png deleted file mode 100644 index 46f6202..0000000 Binary files a/data/flags/ch.png and /dev/null differ diff --git a/data/flags/cu.png b/data/flags/cu.png deleted file mode 100644 index 8afa1bd..0000000 Binary files a/data/flags/cu.png and /dev/null differ diff --git a/data/flags/cz.png b/data/flags/cz.png deleted file mode 100644 index 699a4f0..0000000 Binary files a/data/flags/cz.png and /dev/null differ diff --git a/data/flags/de.png b/data/flags/de.png deleted file mode 100644 index 6d0f503..0000000 Binary files a/data/flags/de.png and /dev/null differ diff --git a/data/flags/dj.png b/data/flags/dj.png deleted file mode 100644 index 81e6d07..0000000 Binary files a/data/flags/dj.png and /dev/null differ diff --git a/data/flags/dk.png b/data/flags/dk.png deleted file mode 100644 index 0d637dc..0000000 Binary files a/data/flags/dk.png and /dev/null differ diff --git a/data/flags/dz.png b/data/flags/dz.png deleted file mode 100644 index 9993cd9..0000000 Binary files a/data/flags/dz.png and /dev/null differ diff --git a/data/flags/ee.png b/data/flags/ee.png deleted file mode 100644 index 8bcdbf4..0000000 Binary files a/data/flags/ee.png and /dev/null differ diff --git a/data/flags/eg.png b/data/flags/eg.png deleted file mode 100644 index f8c1a36..0000000 Binary files a/data/flags/eg.png and /dev/null differ diff --git a/data/flags/es.png b/data/flags/es.png deleted file mode 100644 index 1ed6e7a..0000000 Binary files a/data/flags/es.png and /dev/null differ diff --git a/data/flags/eu.png b/data/flags/eu.png deleted file mode 100644 index 61e2ff6..0000000 Binary files a/data/flags/eu.png and /dev/null differ diff --git a/data/flags/fi.png b/data/flags/fi.png deleted file mode 100644 index 4f098f5..0000000 Binary files a/data/flags/fi.png and /dev/null differ diff --git a/data/flags/fr.png b/data/flags/fr.png deleted file mode 100644 index bd4e18a..0000000 Binary files a/data/flags/fr.png and /dev/null differ diff --git a/data/flags/gb.png b/data/flags/gb.png deleted file mode 100644 index 486303c..0000000 Binary files a/data/flags/gb.png and /dev/null differ diff --git a/data/flags/ge.png b/data/flags/ge.png deleted file mode 100644 index 4fe01bd..0000000 Binary files a/data/flags/ge.png and /dev/null differ diff --git a/data/flags/gr.png b/data/flags/gr.png deleted file mode 100644 index 2a20e8a..0000000 Binary files a/data/flags/gr.png and /dev/null differ diff --git a/data/flags/hr.png b/data/flags/hr.png deleted file mode 100644 index d65bcc5..0000000 Binary files a/data/flags/hr.png and /dev/null differ diff --git a/data/flags/hu.png b/data/flags/hu.png deleted file mode 100644 index 7fd5c9c..0000000 Binary files a/data/flags/hu.png and /dev/null differ diff --git a/data/flags/il.png b/data/flags/il.png deleted file mode 100644 index e48e497..0000000 Binary files a/data/flags/il.png and /dev/null differ diff --git a/data/flags/in.png b/data/flags/in.png deleted file mode 100644 index 7ca0945..0000000 Binary files a/data/flags/in.png and /dev/null differ diff --git a/data/flags/iq.png b/data/flags/iq.png deleted file mode 100644 index 250f2b0..0000000 Binary files a/data/flags/iq.png and /dev/null differ diff --git a/data/flags/is.png b/data/flags/is.png deleted file mode 100644 index 85b9f3a..0000000 Binary files a/data/flags/is.png and /dev/null differ diff --git a/data/flags/it.png b/data/flags/it.png deleted file mode 100644 index d515ffa..0000000 Binary files a/data/flags/it.png and /dev/null differ diff --git a/data/flags/jo.png b/data/flags/jo.png deleted file mode 100644 index 7c8d1f0..0000000 Binary files a/data/flags/jo.png and /dev/null differ diff --git a/data/flags/jp.png b/data/flags/jp.png deleted file mode 100644 index 984fc19..0000000 Binary files a/data/flags/jp.png and /dev/null differ diff --git a/data/flags/km.png b/data/flags/km.png deleted file mode 100644 index d4ed3b4..0000000 Binary files a/data/flags/km.png and /dev/null differ diff --git a/data/flags/kr.png b/data/flags/kr.png deleted file mode 100644 index 43730b1..0000000 Binary files a/data/flags/kr.png and /dev/null differ diff --git a/data/flags/kw.png b/data/flags/kw.png deleted file mode 100644 index 893b433..0000000 Binary files a/data/flags/kw.png and /dev/null differ diff --git a/data/flags/la.png b/data/flags/la.png deleted file mode 100644 index 9000553..0000000 Binary files a/data/flags/la.png and /dev/null differ diff --git a/data/flags/lb.png b/data/flags/lb.png deleted file mode 100644 index f4e7102..0000000 Binary files a/data/flags/lb.png and /dev/null differ diff --git a/data/flags/lt.png b/data/flags/lt.png deleted file mode 100644 index d5ccfa9..0000000 Binary files a/data/flags/lt.png and /dev/null differ diff --git a/data/flags/lv.png b/data/flags/lv.png deleted file mode 100644 index a2ce007..0000000 Binary files a/data/flags/lv.png and /dev/null differ diff --git a/data/flags/ly.png b/data/flags/ly.png deleted file mode 100644 index d2f1656..0000000 Binary files a/data/flags/ly.png and /dev/null differ diff --git a/data/flags/ma.png b/data/flags/ma.png deleted file mode 100644 index 0b3730e..0000000 Binary files a/data/flags/ma.png and /dev/null differ diff --git a/data/flags/mk.png b/data/flags/mk.png deleted file mode 100644 index 32cc584..0000000 Binary files a/data/flags/mk.png and /dev/null differ diff --git a/data/flags/mn.png b/data/flags/mn.png deleted file mode 100644 index c4ce870..0000000 Binary files a/data/flags/mn.png and /dev/null differ diff --git a/data/flags/mx.png b/data/flags/mx.png deleted file mode 100644 index f48cb27..0000000 Binary files a/data/flags/mx.png and /dev/null differ diff --git a/data/flags/nl.png b/data/flags/nl.png deleted file mode 100644 index 7c7b04d..0000000 Binary files a/data/flags/nl.png and /dev/null differ diff --git a/data/flags/no.png b/data/flags/no.png deleted file mode 100644 index defe18f..0000000 Binary files a/data/flags/no.png and /dev/null differ diff --git a/data/flags/om.png b/data/flags/om.png deleted file mode 100644 index 4d21089..0000000 Binary files a/data/flags/om.png and /dev/null differ diff --git a/data/flags/pl.png b/data/flags/pl.png deleted file mode 100644 index cfadbe5..0000000 Binary files a/data/flags/pl.png and /dev/null differ diff --git a/data/flags/ps.png b/data/flags/ps.png deleted file mode 100644 index d0f1c9c..0000000 Binary files a/data/flags/ps.png and /dev/null differ diff --git a/data/flags/pt.png b/data/flags/pt.png deleted file mode 100644 index a805a3d..0000000 Binary files a/data/flags/pt.png and /dev/null differ diff --git a/data/flags/qa.png b/data/flags/qa.png deleted file mode 100644 index e1cb69d..0000000 Binary files a/data/flags/qa.png and /dev/null differ diff --git a/data/flags/qc.png b/data/flags/qc.png deleted file mode 100644 index c2b9c44..0000000 Binary files a/data/flags/qc.png and /dev/null differ diff --git a/data/flags/ro.png b/data/flags/ro.png deleted file mode 100644 index 3afd178..0000000 Binary files a/data/flags/ro.png and /dev/null differ diff --git a/data/flags/ru.png b/data/flags/ru.png deleted file mode 100644 index 33b2176..0000000 Binary files a/data/flags/ru.png and /dev/null differ diff --git a/data/flags/sa.png b/data/flags/sa.png deleted file mode 100644 index 759b86d..0000000 Binary files a/data/flags/sa.png and /dev/null differ diff --git a/data/flags/sd.png b/data/flags/sd.png deleted file mode 100644 index d9249ce..0000000 Binary files a/data/flags/sd.png and /dev/null differ diff --git a/data/flags/se.png b/data/flags/se.png deleted file mode 100644 index 53d0344..0000000 Binary files a/data/flags/se.png and /dev/null differ diff --git a/data/flags/si.png b/data/flags/si.png deleted file mode 100644 index f7287ab..0000000 Binary files a/data/flags/si.png and /dev/null differ diff --git a/data/flags/sk.png b/data/flags/sk.png deleted file mode 100644 index e4517cb..0000000 Binary files a/data/flags/sk.png and /dev/null differ diff --git a/data/flags/so.png b/data/flags/so.png deleted file mode 100644 index c740084..0000000 Binary files a/data/flags/so.png and /dev/null differ diff --git a/data/flags/sr.png b/data/flags/sr.png deleted file mode 100644 index 1f668f4..0000000 Binary files a/data/flags/sr.png and /dev/null differ diff --git a/data/flags/sy.png b/data/flags/sy.png deleted file mode 100644 index f74e6b8..0000000 Binary files a/data/flags/sy.png and /dev/null differ diff --git a/data/flags/th.png b/data/flags/th.png deleted file mode 100644 index 1b55adf..0000000 Binary files a/data/flags/th.png and /dev/null differ diff --git a/data/flags/tn.png b/data/flags/tn.png deleted file mode 100644 index 9b57531..0000000 Binary files a/data/flags/tn.png and /dev/null differ diff --git a/data/flags/tr.png b/data/flags/tr.png deleted file mode 100644 index 395e0b7..0000000 Binary files a/data/flags/tr.png and /dev/null differ diff --git a/data/flags/ua.png b/data/flags/ua.png deleted file mode 100644 index e981703..0000000 Binary files a/data/flags/ua.png and /dev/null differ diff --git a/data/flags/uk.png b/data/flags/uk.png deleted file mode 100644 index 486303c..0000000 Binary files a/data/flags/uk.png and /dev/null differ diff --git a/data/flags/un.png b/data/flags/un.png deleted file mode 100644 index 47c6f74..0000000 Binary files a/data/flags/un.png and /dev/null differ diff --git a/data/flags/us.png b/data/flags/us.png deleted file mode 100644 index d10ca59..0000000 Binary files a/data/flags/us.png and /dev/null differ diff --git a/data/flags/uy.png b/data/flags/uy.png deleted file mode 100644 index 9990421..0000000 Binary files a/data/flags/uy.png and /dev/null differ diff --git a/data/flags/vn.png b/data/flags/vn.png deleted file mode 100644 index 3fc1c81..0000000 Binary files a/data/flags/vn.png and /dev/null differ diff --git a/data/flags/ye.png b/data/flags/ye.png deleted file mode 100644 index be7080c..0000000 Binary files a/data/flags/ye.png and /dev/null differ diff --git a/data/flags/yu.png b/data/flags/yu.png deleted file mode 100644 index 9470101..0000000 Binary files a/data/flags/yu.png and /dev/null differ diff --git a/data/flags/zz.png b/data/flags/zz.png deleted file mode 100644 index 4f402e4..0000000 Binary files a/data/flags/zz.png and /dev/null differ diff --git a/data/man/CMakeLists.txt b/data/man/CMakeLists.txt index 318c5ba..822c093 100644 --- a/data/man/CMakeLists.txt +++ b/data/man/CMakeLists.txt @@ -19,7 +19,6 @@ function(BUILD_MAN_PAGE _sources _src _dst) endfunction() build_man_page(MAN1_OUTPUT "ddm.rst" "ddm.1") -build_man_page(MAN1_OUTPUT "ddm-greeter.rst" "ddm-greeter.1") build_man_page(MAN5_OUTPUT "ddm.conf.rst" "ddm.conf.5") build_man_page(MAN5_OUTPUT "ddm-state.conf.rst" "ddm-state.conf.5") diff --git a/data/man/sddm-state.conf.rst.in b/data/man/ddm-state.conf.rst.in similarity index 85% rename from data/man/sddm-state.conf.rst.in rename to data/man/ddm-state.conf.rst.in index b6475d4..1814131 100644 --- a/data/man/sddm-state.conf.rst.in +++ b/data/man/ddm-state.conf.rst.in @@ -2,11 +2,11 @@ state.conf ============ ----------------------------------- -ddm display manager configuration ----------------------------------- +----------------- +ddm configuration +----------------- -:Date: August 2014 +:Date: Dec 2025 :Version: ddm @DDM_VERSION_STRING@ :Manual section: 5 :Manual group: ddm diff --git a/data/man/ddm.conf.rst.in b/data/man/ddm.conf.rst.in new file mode 100644 index 0000000..326fe89 --- /dev/null +++ b/data/man/ddm.conf.rst.in @@ -0,0 +1,147 @@ +=========== + ddm.conf +=========== + +---------------------------------- +ddm display manager configuration +---------------------------------- + +:Date: Dec 2025 +:Version: ddm @DDM_VERSION_STRING@ +:Manual section: 5 +:Manual group: ddm + +SYNOPSIS +======== + +Configuration loads all files in the configuration directories followed by the configuration file in the order listed below with the latter having highest precedence. Changes should be made to the local configurations. + +**@SYSTEM_CONFIG_DIR@** + System configuration directory + +**@CONFIG_DIR@** + Local configuration directory + +**@CONFIG_FILE@** + Local configuration file for compatibility + +DESCRIPTION +=========== + +This file configures various parameters of the ddm display manager **ddm**\(1\). +If this file is not available, default values are used. + +OPTIONS +======= + +[General] section: + +`HaltCommand=` + Halt command. + Default value is "@HALT_COMMAND@". + +`RebootCommand=` + Reboot command. + Default value is "@REBOOT_COMMAND@". + +`Namespaces=` + Comma-separated list of paths bound to Linux namespaces to enter with + setns() before starting the user session. For example, to enter network + namespace `mynet` created with `ip netns add mynet`, the value might be + `/run/netns/mynet`. Default value is empty. (The value is ignored if + the operating system is not Linux.) + +[Theme] section: + +`CursorTheme=` + Name of the cursor theme to be set before starting + the display server. + +`CursorSize=` + Cursor size to be set before starting the display server. + +[X11] section: + +`ServerPath=` + Path of the X server. + Default value is "/usr/bin/X". + +`ServerArguments=` + Arguments to the X server. + Default value is "-nolisten tcp". + +`SessionDir=` + Comma-separated list of directories containing session files. + Default value is "/usr/local/share/xsessions,/usr/share/xsessions". + +`SessionCommand=` + Path of script to execute when starting the user session. This script + receives the value of the "Exec" setting in the ".desktop" file of the selected + session and runs it. + Default value is "@SESSION_COMMAND@". + +`SessionLogFile=` + Path to the user session log file, relative to the home directory. + Default value is ".local/share/ddm/xorg-session.log". + +`DisplayCommand=` + Path of script to execute when starting the display server. + The script will be executed as root when General.DisplayServer + is "x11", otherwise as ddm user. + Default value is "@DATA_INSTALL_DIR@/scripts/Xsetup". + +`DisplayStopCommand=` + Path of script to execute when stopping the display server. + The script will be executed as root when General.DisplayServer + is "x11", otherwise as ddm user. + Default value is "@DATA_INSTALL_DIR@/scripts/Xstop". + +[Wayland] section: + +`SessionDir=` + Comma-separated list of directories containing session files. + Default value is "/usr/local/share/wayland-sessions,/usr/share/wayland-sessions". + +`SessionCommand=` + Path of script to execute when starting the user session. This script + receives the value of the "Exec" setting in the ".desktop" file of the selected + session and run it. + Default value is "@WAYLAND_SESSION_COMMAND@". + +`SessionLogFile=` + Path to the user session log file, relative to the home directory. + Default value is ".local/share/ddm/wayland-session.log". + +[Single] section: + +`SessionCommand=` + Path of script to execute when starting the user session for Treeland. + This script receives the value of the "Exec" setting in the ".desktop" file + of the selected session and run it. + Default value is "@WAYLAND_SESSION_COMMAND@". + +[Users] section: + +`DefaultPath=` + Default path to set after successfully logging in. + This is also where DDM looks for programs. + Default value is "/usr/local/bin:/usr/bin:/bin". + +`RememberLastUser=` + If this flag is true, LastUser value will updated + on every successful login, if false last user value + won't be updated. + Default value is true. + +`RememberLastSession=` + If this flag is true, LastSession value will updated + on every successful login, if false last session value + won't be updated. + Default value is true. + +SEE ALSO +======== + +**ddm**\(1\) + +The full documentation for ddm is available at https://github.com/ddm/ddm diff --git a/data/man/sddm.rst.in b/data/man/ddm.rst.in similarity index 68% rename from data/man/sddm.rst.in rename to data/man/ddm.rst.in index 0dc122c..4b06981 100644 --- a/data/man/sddm.rst.in +++ b/data/man/ddm.rst.in @@ -2,11 +2,11 @@ ddm ====== ----------------------------------- -the simple desktop display manager ----------------------------------- +--- +DDM +--- -:Date: May 2014 +:Date: Dec 2025 :Version: ddm @DDM_VERSION_STRING@ :Manual section: 1 :Manual group: ddm @@ -19,13 +19,8 @@ ddm [OPTIONS...] DESCRIPTION =========== -ddm is a display and login manager based on Qt technologies. - -Using QtQuick and QML, designers are given the ability to -easily create pleasant, modern looking interfaces for ddm. - -ddm runs the greeter as a system user named **ddm** -whose home directory needs to be set to **/var/lib/ddm**. +ddm is a display and login manager based on Qt technologies and using +Treeland as greeter. If pam and systemd are available, the greeter will go through logind, which will give it access to drm devices. @@ -62,9 +57,6 @@ FILES **@CONFIG_FILE@** Local configuration file for compatibility -**@DATA_INSTALL_DIR@/themes** - Where ddm looks for themes - SEE ALSO ======== diff --git a/data/man/sddm-greeter.rst.in b/data/man/sddm-greeter.rst.in deleted file mode 100644 index 89d369f..0000000 --- a/data/man/sddm-greeter.rst.in +++ /dev/null @@ -1,67 +0,0 @@ -============== - ddm-greeter -============== - ----------------------------- -ddm display manager greeter ----------------------------- - -:Date: May 2014 -:Version: ddm @DDM_VERSION_STRING@ -:Manual section: 1 -:Manual group: ddm - -SYNOPSIS -======== - -ddm-greeter [OPTIONS...] - -DESCRIPTION -=========== - -ddm is a display and login manager based on Qt technologies. - -Using QtQuick and QML, designers are given the ability to -easily create pleasant, modern looking interfaces for ddm. - -ddm-greeter is an auxiliary process that displays the greeter, a graphical -user interface to perform the authentication and select the session to run. - -It is launched by the ddm daemon, end users are not meant to run it. - -OPTIONS -======= - ---theme `PATH` - Specify theme full path. - ---socket `NAME` - Specify the socket used to communicate with ddm daemon. - ---test-mode - Start greeter in test mode. - ---help, -h - Show help message and exit. - -FILES -===== - -**@SYSTEM_CONFIG_DIR@** - System configuration directory - -**@CONFIG_DIR@** - Local configuration directory - -**@CONFIG_FILE@** - Local configuration file for compatibility - -**@DATA_INSTALL_DIR@/themes** - Where ddm looks for themes - -SEE ALSO -======== - -**ddm**\(1\), **ddm.conf**\(5\) - -The full documentation for ddm is available at https://github.com/ddm/ddm diff --git a/data/man/sddm.conf.rst.in b/data/man/sddm.conf.rst.in deleted file mode 100644 index b79472e..0000000 --- a/data/man/sddm.conf.rst.in +++ /dev/null @@ -1,254 +0,0 @@ -=========== - ddm.conf -=========== - ----------------------------------- -ddm display manager configuration ----------------------------------- - -:Date: March 2021 -:Version: ddm @DDM_VERSION_STRING@ -:Manual section: 5 -:Manual group: ddm - -SYNOPSIS -======== - -Configuration loads all files in the configuration directories followed by the configuration file in the order listed below with the latter having highest precedence. Changes should be made to the local configurations. - -**@SYSTEM_CONFIG_DIR@** - System configuration directory - -**@CONFIG_DIR@** - Local configuration directory - -**@CONFIG_FILE@** - Local configuration file for compatibility - -DESCRIPTION -=========== - -This file configures various parameters of the ddm display manager **ddm**\(1\). -If this file is not available, default values are used. - -OPTIONS -======= - -[General] section: - -`DisplayServer=` - Select the display server to use for the greeter. - Valid values are: - - * `x11`: X server running as root. - * `x11-user`: X server running as unprivileged user. - * `wayland`: Wayland compositor as unprivileged user. (Experimental) - - Default value is "x11". - For `x11-user` you might need to configure Xorg.wrap(1). - -`HaltCommand=` - Halt command. - Default value is "@HALT_COMMAND@". - -`RebootCommand=` - Reboot command. - Default value is "@REBOOT_COMMAND@". - -`Numlock=` - Change numlock state when **ddm-greeter** starts. - Valid values are `on`, `off` or `none`. - If property is set to `none`, numlock won't be changed. - Default value is "none". - -`InputMethod=` - Set the Qt input method for the greeter. - Tablet users with Qt Virtual Keyboard installed can set this - to "qtvirtualkeyboard" for the on-screen keyboard. - Other known values are "ibus" for the Intelligent Input Bus, - or "compose" for dead keys support. - Leave this empty if unsure. - -`Namespaces=` - Comma-separated list of paths bound to Linux namespaces to enter with - setns() before starting the user session. For example, to enter network - namespace `mynet` created with `ip netns add mynet`, the value might be - `/run/netns/mynet`. Default value is empty. (The value is ignored if - the operating system is not Linux.) - -[Theme] section: - -`ThemeDir=` - Path of the directory containing theme files. - Default value is "@DATA_INSTALL_DIR@/themes". - -`Current=` - Name of the current theme. - By default this setting is empty, meaning the embedded theme - will be used. - -`FacesDir=` - Path of the directory containing face files, - face files should be in username.face.icon format. - Default value is "@DATA_INSTALL_DIR@/faces". - -`CursorTheme=` - Name of the cursor theme to be set before starting - the display server. - -`CursorSize=` - Cursor size to be set before starting the display server. - -`Font=` - Name of the font to be set before starting the - display server. Please note that the theme can still override this option. - -`EnableAvatars=` - When enabled, home directories are searched for ".face.icon" images to - display as their avatars. This can be slow on some file systems. - When disabled, all avatars will be default. Themes may choose to hide - them altogether. - Default value is true. - -[X11] section: - -`ServerPath=` - Path of the X server. - Default value is "/usr/bin/X". - -`ServerArguments=` - Arguments to the X server. - Default value is "-nolisten tcp". - -`XephyrPath=` - Path of the Xephyr. - Default value is "/usr/bin/Xephyr". - -`SessionDir=` - Comma-separated list of directories containing session files. - Default value is "/usr/local/share/xsessions,/usr/share/xsessions". - -`SessionCommand=` - Path of script to execute when starting the user session. This script - receives the value of the "Exec" setting in the ".desktop" file of the selected - session and runs it. - Default value is "@SESSION_COMMAND@". - -`SessionLogFile=` - Path to the user session log file, relative to the home directory. - Default value is ".local/share/ddm/xorg-session.log". - -`DisplayCommand=` - Path of script to execute when starting the display server. - The script will be executed as root when General.DisplayServer - is "x11", otherwise as ddm user. - Default value is "@DATA_INSTALL_DIR@/scripts/Xsetup". - -`DisplayStopCommand=` - Path of script to execute when stopping the display server. - The script will be executed as root when General.DisplayServer - is "x11", otherwise as ddm user. - Default value is "@DATA_INSTALL_DIR@/scripts/Xstop". - -`MinimumVT=` - Minimum virtual terminal number that will be used - by the first display. Virtual terminal number will - increase as new displays added. - This setting is no longer available since DDM v0.20. - -`EnableHiDPI=` - Enables Qt's automatic HiDPI scaling. - Can be either "true" or "false". - Default value is "true". - -The `XauthPath=` option is no longer necessary, libxau is used instead. - -The `UserAuthFile=` option was removed, the file is always created as -`/tmp/xauth_XXXXX`. This is necessary for to the use of `FamilyWild` entries. - -[Wayland] section: - -`CompositorCommand=` - Path of the compositor to execute when starting the greeter. - Default value is "weston --shell=fullscreen-shell.so". - -`SessionDir=` - Comma-separated list of directories containing session files. - Default value is "/usr/local/share/wayland-sessions,/usr/share/wayland-sessions". - -`SessionCommand=` - Path of script to execute when starting the user session. This script - receives the value of the "Exec" setting in the ".desktop" file of the selected - session and run it. - Default value is "@WAYLAND_SESSION_COMMAND@". - -`SessionLogFile=` - Path to the user session log file, relative to the home directory. - Default value is ".local/share/ddm/wayland-session.log". - -`EnableHiDPI=` - Enables Qt's automatic HiDPI scaling. - Can be either "true" or "false". - Default value is "true". - -[Users] section: - -`DefaultPath=` - Default path to set after successfully logging in. - This is also where DDM looks for programs. - Default value is "/usr/local/bin:/usr/bin:/bin". - -`MinimumUid=` - Minimum user id of the users to be listed in the - user interface. - Default value is @UID_MIN@. - -`MaximumUid=` - Maximum user id of the users to be listed in the - user interface. - Default value is @UID_MAX@ - -`HideUsers=` - Comma-separated list of Users that shouldn't show up in the user list. - Default value is empty. - -`HideShells=` - Comma-separated list of Shells of users that shouldn't show up in the user list. - Default value is empty. - -`RememberLastUser=` - If this flag is true, LastUser value will updated - on every successful login, if false last user value - won't be updated. - Default value is true. - -`RememberLastSession=` - If this flag is true, LastSession value will updated - on every successful login, if false last session value - won't be updated. - Default value is true. - -[Autologin] section: - -`User=` - Name of the user to automatically log in when the - system starts first time. - Default value is empty. - -`Session=` - Name of the session to automatically log in when the - system starts first time. - Default value is empty. - -`Relogin=` - If true and User and Session are set automatic login will - kick in again on session exit, otherwise it will work - only the first time. - Default value is false. - -SEE ALSO -======== - -**ddm**\(1\) - -The full documentation for ddm is available at https://github.com/ddm/ddm diff --git a/data/systemd/CMakeLists.txt b/data/systemd/CMakeLists.txt deleted file mode 100644 index e4a01e2..0000000 --- a/data/systemd/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -if (NOT DEFINED SYSTEMD_SYSTEM_UNIT_DIR) - find_package(PkgConfig REQUIRED) - pkg_check_modules(Systemd REQUIRED systemd) - pkg_get_variable(SYSTEMD_SYSTEM_UNIT_DIR systemd systemduserunitdir) -endif() diff --git a/debian/control b/debian/control index 2e6c183..e5f73c8 100644 --- a/debian/control +++ b/debian/control @@ -8,10 +8,6 @@ Build-Depends: debhelper-compat (= 13), libpam0g-dev, libsystemd-dev [linux-any], libxau-dev, - libxcb-xkb-dev, - libxcb1-dev, - libxkbcommon-dev, - libxcb-ewmh-dev, qt6-base-dev (>= 6.6.1~), qt6-declarative-dev (>= 6.6.1~), qt6-tools-dev, diff --git a/services/CMakeLists.txt b/services/CMakeLists.txt index d584fae..fbf54e5 100644 --- a/services/CMakeLists.txt +++ b/services/CMakeLists.txt @@ -1,10 +1,8 @@ -if(SYSTEMD_FOUND) - configure_file(ddm.service.in ddm.service) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ddm.service" DESTINATION "${SYSTEMD_SYSTEM_UNIT_DIR}") +configure_file(ddm.service.in ddm.service) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ddm.service" DESTINATION "${SYSTEMD_SYSTEM_UNIT_DIR}") - configure_file(ddm-sysuser.conf.in ddm-sysuser.conf) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ddm-sysuser.conf" DESTINATION "${SYSTEMD_SYSUSERS_DIR}" RENAME dde.conf) -endif() +configure_file(ddm-sysuser.conf.in ddm-sysuser.conf) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ddm-sysuser.conf" DESTINATION "${SYSTEMD_SYSUSERS_DIR}" RENAME dde.conf) # systemd-tmpfiles can be used standalone without other systemd parts if(DEFINED SYSTEMD_TMPFILES_DIR) @@ -12,24 +10,8 @@ if(DEFINED SYSTEMD_TMPFILES_DIR) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ddm-tmpfiles.conf" DESTINATION "${SYSTEMD_TMPFILES_DIR}" RENAME ddm.conf) endif() -if(USE_ELOGIND) - set(LOGIND_PAM_MODULE "pam_elogind.so") -else() - set(LOGIND_PAM_MODULE "pam_systemd.so") -endif() -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ddm-greeter.pam.in" "${CMAKE_CURRENT_BINARY_DIR}/ddm-greeter.pam") - if(EXISTS "/etc/debian_version") - install(FILES debian.ddm-autologin.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME ddm-autologin) - install(FILES debian.ddm-greeter.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME ddm-greeter) install(FILES debian.ddm.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME ddm) else() - if(HAVE_PAM_FAILLOCK) - install(FILES ddm-autologin.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME ddm-autologin) - else() - install(FILES ddm-autologin-tally2.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME ddm-autologin) - endif() - install(FILES ddm.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME ddm) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ddm-greeter.pam" DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME ddm-greeter) endif() diff --git a/services/ddm-autologin-tally2.pam b/services/ddm-autologin-tally2.pam deleted file mode 100644 index 99729bc..0000000 --- a/services/ddm-autologin-tally2.pam +++ /dev/null @@ -1,13 +0,0 @@ -#%PAM-1.0 -auth required pam_env.so -auth required pam_tally2.so file=/var/log/tallylog onerr=succeed -auth required pam_shells.so -auth required pam_nologin.so -auth required pam_permit.so --auth optional pam_gnome_keyring.so --auth optional pam_kwallet5.so -account include system-local-login -password include system-local-login -session include system-local-login --session optional pam_gnome_keyring.so auto_start --session optional pam_kwallet5.so auto_start diff --git a/services/ddm-autologin.pam b/services/ddm-autologin.pam deleted file mode 100644 index b42991e..0000000 --- a/services/ddm-autologin.pam +++ /dev/null @@ -1,13 +0,0 @@ -#%PAM-1.0 -auth required pam_env.so -auth required pam_faillock.so preauth -auth required pam_shells.so -auth required pam_nologin.so -auth required pam_permit.so --auth optional pam_gnome_keyring.so --auth optional pam_kwallet5.so -account include system-local-login -password include system-local-login -session include system-local-login --session optional pam_gnome_keyring.so auto_start --session optional pam_kwallet5.so auto_start diff --git a/services/ddm-greeter.pam.in b/services/ddm-greeter.pam.in deleted file mode 100644 index d41792d..0000000 --- a/services/ddm-greeter.pam.in +++ /dev/null @@ -1,17 +0,0 @@ -#%PAM-1.0 - -# Load environment from /etc/environment and ~/.pam_environment -auth required pam_env.so - -# Always let the greeter start without authentication -auth required pam_permit.so - -# No action required for account management -account required pam_permit.so - -# Can't change password -password required pam_deny.so - -# Setup session -session required pam_unix.so -session optional @LOGIND_PAM_MODULE@ diff --git a/services/ddm.service.in b/services/ddm.service.in index 6231442..06e4c8c 100644 --- a/services/ddm.service.in +++ b/services/ddm.service.in @@ -14,5 +14,14 @@ Before=seatd.service ExecStart=@CMAKE_INSTALL_FULL_BINDIR@/ddm Restart=always +CapabilityBoundingSet=CAP_CHOWN CAP_FOWNER CAP_KILL CAP_SETGID CAP_SETUID CAP_SYS_ADMIN CAP_SYS_BOOT CAP_SYS_CHROOT CAP_SYS_TTY_CONFIG +OOMScoreAdjust=-300 +Nice=-15 +PrivateIPC=true +ProtectClock=true +ProtectKernelTunables=true +ProtectKernelModules=true +RestrictSUIDSGID=true + [Install] Alias=display-manager.service diff --git a/services/debian.ddm-autologin.pam b/services/debian.ddm-autologin.pam deleted file mode 100644 index d595682..0000000 --- a/services/debian.ddm-autologin.pam +++ /dev/null @@ -1,32 +0,0 @@ -#%PAM-1.0 - -# Block login if they are globally disabled -auth requisite pam_nologin.so -auth required pam_permit.so - -@include common-account - -# SELinux needs to be the first session rule. This ensures that any -# lingering context has been cleared. Without this it is possible that a -# module could execute code in the wrong domain. -session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close -# Create a new session keyring. -session optional pam_keyinit.so force revoke -session required pam_limits.so -session required pam_loginuid.so -@include common-session -# SELinux needs to intervene at login time to ensure that the process starts -# in the proper default security context. Only sessions which are intended -# to run in the user's context should be run after this. -session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open - -@include common-password - -# From the pam_env man page -# Since setting of PAM environment variables can have side effects to other modules, this module should be the last one on the stack. - -# Load environment from /etc/environment -session required pam_env.so - -# Load environment from /etc/default/locale -session required pam_env.so envfile=/etc/default/locale diff --git a/services/debian.ddm-greeter.pam b/services/debian.ddm-greeter.pam deleted file mode 100644 index 78aed41..0000000 --- a/services/debian.ddm-greeter.pam +++ /dev/null @@ -1,31 +0,0 @@ -#%PAM-1.0 - -auth required pam_permit.so - -@include common-account - -# SELinux needs to be the first session rule. This ensures that any -# lingering context has been cleared. Without this it is possible that a -# module could execute code in the wrong domain. -session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close -# Create a new session keyring. -session optional pam_keyinit.so force revoke -session required pam_limits.so -session required pam_loginuid.so -@include common-session -# SELinux needs to intervene at login time to ensure that the process starts -# in the proper default security context. Only sessions which are intended -# to run in the user's context should be run after this. -session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open - -# Can't change password -password required pam_deny.so - -# From the pam_env man page -# Since setting of PAM environment variables can have side effects to other modules, this module should be the last one on the stack. - -# Load environment from /etc/environment -session required pam_env.so - -# Load environment from /etc/default/locale -session required pam_env.so envfile=/etc/default/locale diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 75519d0..7e01138 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -4,12 +4,9 @@ set(PUBLIC_HEADERS ${CMAKE_SOURCE_DIR}/src/common/Configuration.h ${CMAKE_SOURCE_DIR}/src/common/MessageHandler.h ${CMAKE_SOURCE_DIR}/src/common/Messages.h - ${CMAKE_SOURCE_DIR}/src/common/SafeDataStream.h ${CMAKE_SOURCE_DIR}/src/common/Session.h ${CMAKE_SOURCE_DIR}/src/common/SignalHandler.h ${CMAKE_SOURCE_DIR}/src/common/SocketWriter.h - ${CMAKE_SOURCE_DIR}/src/common/ThemeConfig.h - ${CMAKE_SOURCE_DIR}/src/common/ThemeMetadata.h ${CMAKE_SOURCE_DIR}/src/common/VirtualTerminal.h ${CMAKE_SOURCE_DIR}/src/common/XAuth.h ${CMAKE_BINARY_DIR}/src/common/Constants.h @@ -19,12 +16,9 @@ set(PUBLIC_HEADERS set(SRCS ${CMAKE_SOURCE_DIR}/src/common/ConfigReader.cpp ${CMAKE_SOURCE_DIR}/src/common/Configuration.cpp - ${CMAKE_SOURCE_DIR}/src/common/SafeDataStream.cpp ${CMAKE_SOURCE_DIR}/src/common/Session.cpp ${CMAKE_SOURCE_DIR}/src/common/SignalHandler.cpp ${CMAKE_SOURCE_DIR}/src/common/SocketWriter.cpp - ${CMAKE_SOURCE_DIR}/src/common/ThemeConfig.cpp - ${CMAKE_SOURCE_DIR}/src/common/ThemeMetadata.cpp ${CMAKE_SOURCE_DIR}/src/common/VirtualTerminal.cpp ${CMAKE_SOURCE_DIR}/src/common/XAuth.cpp ${CMAKE_SOURCE_DIR}/src/common/LogindDBusTypes.cpp diff --git a/src/common/Configuration.h b/src/common/Configuration.h index 011f1a3..b258980 100644 --- a/src/common/Configuration.h +++ b/src/common/Configuration.h @@ -34,84 +34,44 @@ namespace DDM { // Name File Sections and/or Entries (but anything else too, it's a class) - Entries in a Config are assumed to be in the General section Config(MainConfig, QStringLiteral(CONFIG_FILE), QStringLiteral(CONFIG_DIR), QStringLiteral(SYSTEM_CONFIG_DIR), - enum NumState { NUM_NONE, NUM_SET_ON, NUM_SET_OFF }; // Name Type Default value Description - // TODO: Change default to x11-user in a future release - Entry(DisplayServer, QString, _S("single"), _S("Which display server should be used.\n" - "Valid values are: x11, x11-user, wayland. Wayland support is experimental")); Entry(HaltCommand, QString, _S(HALT_COMMAND), _S("Halt command")); Entry(RebootCommand, QString, _S(REBOOT_COMMAND), _S("Reboot command")); - Entry(Numlock, NumState, NUM_NONE, _S("Initial NumLock state. Can be on, off or none.\n" - "If property is set to none, numlock won't be changed\n" - "NOTE: Currently ignored if autologin is enabled.")); - Entry(InputMethod, QString, QStringLiteral("qtvirtualkeyboard"), _S("Input method module")); Entry(Namespaces, QStringList, QStringList(), _S("Comma-separated list of Linux namespaces for user session to enter")); - Entry(GreeterEnvironment, QStringList, QStringList(), _S("Comma-separated list of environment variables to be set")); // Name Entries (but it's a regular class again) Section(Theme, - Entry(ThemeDir, QString, _S(DATA_INSTALL_DIR "/themes"), _S("Theme directory path")); - Entry(Current, QString, _S(""), _S("Current theme name")); - Entry(FacesDir, QString, _S(DATA_INSTALL_DIR "/faces"), _S("Global directory for user avatars\n" - "The files should be named .face.icon")); Entry(CursorTheme, QString, QString(), _S("Cursor theme used in the greeter")); Entry(CursorSize, QString, QString(), _S("Cursor size used in the greeter")); - Entry(Font, QString, QString(), _S("Font used in the greeter")); - Entry(EnableAvatars, bool, true, _S("Enable display of custom user avatars")); - Entry(DisableAvatarsThreshold,int, 7, _S("Number of users to use as threshold\n" - "above which avatars are disabled\n" - "unless explicitly enabled with EnableAvatars")); ); // TODO: Not absolutely sure if everything belongs here. Xsessions, VT and probably some more seem universal Section(X11, Entry(ServerPath, QString, _S("/usr/bin/X"), _S("Path to X server binary")); Entry(ServerArguments, QString, _S("-nolisten tcp"), _S("Arguments passed to the X server invocation")); - Entry(XephyrPath, QString, _S("/usr/bin/Xephyr"), _S("Path to Xephyr binary")); Entry(SessionDir, QStringList, {_S("/usr/local/share/xsessions"), _S("/usr/share/xsessions")}, _S("Comma-separated list of directories containing available X sessions")); Entry(SessionCommand, QString, _S(SESSION_COMMAND), _S("Path to a script to execute when starting the desktop session")); Entry(SessionLogFile, QString, _S(".local/share/ddm/xorg-session.log"), _S("Path to the user session log file")); Entry(DisplayCommand, QString, _S(DATA_INSTALL_DIR "/scripts/Xsetup"), _S("Path to a script to execute when starting the display server")); Entry(DisplayStopCommand, QString, _S(DATA_INSTALL_DIR "/scripts/Xstop"), _S("Path to a script to execute when stopping the display server")); - Entry(EnableHiDPI, bool, true, _S("Enable Qt's automatic high-DPI scaling")); ); Section(Wayland, - Entry(CompositorCommand, QString, _S("weston --shell=fullscreen-shell.so"), _S("Path of the Wayland compositor to execute when starting the greeter")); Entry(SessionDir, QStringList, {_S("/usr/local/share/wayland-sessions"), _S("/usr/share/wayland-sessions")}, _S("Comma-separated list of directories containing available Wayland sessions")); Entry(SessionCommand, QString, _S(WAYLAND_SESSION_COMMAND), _S("Path to a script to execute when starting the desktop session")); Entry(SessionLogFile, QString, _S(".local/share/ddm/wayland-session.log"),_S("Path to the user session log file")); - Entry(EnableHiDPI, bool, true, _S("Enable Qt's automatic high-DPI scaling")); ); Section(Single, - Entry(CompositorCommand, QString, _S("treeland"), _S("Path of the Wayland compositor to execute when starting the greeter")); - Entry(SessionDir, QStringList, {_S("/usr/local/share/wayland-sessions"), - _S("/usr/share/wayland-sessions")}, _S("Comma-separated list of directories containing available Wayland sessions")); Entry(SessionCommand, QString, _S(WAYLAND_SESSION_COMMAND), _S("Path to a script to execute when starting the desktop session")); - Entry(SessionLogFile, QString, _S(".local/share/ddm/wayland-session.log"),_S("Path to the user session log file")); - Entry(EnableHiDPI, bool, true, _S("Enable Qt's automatic high-DPI scaling")); ); Section(Users, Entry(DefaultPath, QString, _S("/usr/local/bin:/usr/bin:/bin"), _S("Default $PATH for logged in users")); - Entry(MinimumUid, int, UID_MIN, _S("Minimum user id for displayed users")); - Entry(MaximumUid, int, UID_MAX, _S("Maximum user id for displayed users")); - Entry(HideUsers, QStringList, QStringList(), _S("Comma-separated list of users that should not be listed")); - Entry(HideShells, QStringList, QStringList(), _S("Comma-separated list of shells.\n" - "Users with these shells as their default won't be listed")); Entry(RememberLastUser, bool, true, _S("Remember the last successfully logged in user")); Entry(RememberLastSession, bool, true, _S("Remember the session of the last successfully logged in user")); - - Entry(ReuseSession, bool, true, _S("When logging in as the same user twice, restore the original session, rather than create a new one")); - ); - - Section(Autologin, - Entry(User, QString, QString(), _S("Username for autologin session")); - Entry(Session, QString, QString(), _S("Name of session file for autologin session (if empty try last logged in)")); - Entry(Relogin, bool, false, _S("Whether ddm should automatically log back into sessions when they exit")); ); ); @@ -126,27 +86,6 @@ namespace DDM { extern MainConfig mainConfig; extern StateConfig stateConfig; - - inline QTextStream& operator>>(QTextStream &str, MainConfig::NumState &state) { - QString text = str.readLine().trimmed(); - if (text.compare(QLatin1String("on"), Qt::CaseInsensitive) == 0) - state = MainConfig::NUM_SET_ON; - else if (text.compare(QLatin1String("off"), Qt::CaseInsensitive) == 0) - state = MainConfig::NUM_SET_OFF; - else - state = MainConfig::NUM_NONE; - return str; - } - - inline QTextStream& operator<<(QTextStream &str, const MainConfig::NumState &state) { - if (state == MainConfig::NUM_SET_ON) - str << "on"; - else if (state == MainConfig::NUM_SET_OFF) - str << "off"; - else - str << "none"; - return str; - } } #endif // DDM_CONFIGURATION_H diff --git a/src/common/SafeDataStream.cpp b/src/common/SafeDataStream.cpp deleted file mode 100644 index ce132f7..0000000 --- a/src/common/SafeDataStream.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * QDataStream implementation for safe socket operation - * Copyright (C) 2014 Martin Bříza - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include "SafeDataStream.h" - -#include -#include - -namespace DDM { - SafeDataStream::SafeDataStream(QIODevice* device) - : QDataStream(&m_data, QIODevice::ReadWrite) - , m_device(device) { } - - void SafeDataStream::send() { - qint64 length = m_data.length(); - qint64 writtenTotal = 0; - if (!m_device->isOpen()) { - qCritical() << " Auth: SafeDataStream: Could not write any data"; - return; - } - m_device->write((const char*) &length, sizeof(length)); - while (writtenTotal != length) { - qint64 written = m_device->write(m_data.mid(writtenTotal)); - if (written < 0 || !m_device->isOpen()) { - qCritical() << " Auth: SafeDataStream: Could not write all stored data"; - return; - } - writtenTotal += written; - m_device->waitForBytesWritten(-1); - } - - reset(); - } - - void SafeDataStream::receive() { - qint64 length = -1; - - if (!m_device->isOpen()) { - qCritical() << " Auth: SafeDataStream: Could not read from the device"; - return; - } - if (!m_device->bytesAvailable()) - m_device->waitForReadyRead(-1); - m_device->read((char*) &length, sizeof(length)); - - if (length < 0) - return; - reset(); - - while (m_data.length() < length) { - if (!m_device->isOpen()) { - qCritical() << " Auth: SafeDataStream: Could not read from the device"; - return; - } - if (!m_device->bytesAvailable()) - m_device->waitForReadyRead(-1); - m_data.append(m_device->read(length - m_data.length())); - } - } - - void SafeDataStream::reset() { - m_data.clear(); - device()->reset(); - resetStatus(); - } -} diff --git a/src/common/SafeDataStream.h b/src/common/SafeDataStream.h deleted file mode 100644 index 5249b3b..0000000 --- a/src/common/SafeDataStream.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * QDataStream implementation for safe socket operation - * Copyright (C) 2014 Martin Bříza - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef SAFEDATASTREAM_H -#define SAFEDATASTREAM_H - -#include -#include - -namespace DDM { - class SafeDataStream : public QDataStream { - public: - SafeDataStream(QIODevice* device); - void send(); - void receive(); - void reset(); - - private: - QByteArray m_data { }; - QIODevice *m_device { nullptr }; - }; -} - -#endif // SAFEDATASTREAM_H diff --git a/src/common/ThemeConfig.cpp b/src/common/ThemeConfig.cpp deleted file mode 100644 index 3be2647..0000000 --- a/src/common/ThemeConfig.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2023 Fabian Vogt -* Copyright (c) 2016 Pier Luigi Fiorini -* Copyright (c) 2014 David Edmundson -* Copyright (c) 2013 Abdurrahman AVCI -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -#include "ThemeConfig.h" - -#include -#include -#include - -namespace DDM { - ThemeConfig::ThemeConfig(const QString &path, QObject *parent) - : QQmlPropertyMap(this, parent) { - setTo(path); - } - - void ThemeConfig::setTo(const QString &path) { - for(const QString &key : keys()) { - clear(key); - } - - if (path.isNull()) { - qDebug() << "Loaded empty theme configuration"; - return; - } - - qDebug() << "Loading theme configuration from" << path; - - QSettings settings(path, QSettings::IniFormat); - QSettings userSettings(path + QStringLiteral(".user"), QSettings::IniFormat); - - // read default keys - for (const QString &key: settings.allKeys()) { - insert(key, settings.value(key)); - } - // read user set themes overwriting defaults if they exist - for (const QString &key: userSettings.allKeys()) { - if (!userSettings.value(key).toString().isEmpty()) { - insert(key, userSettings.value(key)); - } - } - - //if the main config contains a background, save this to a new config value - //to themes can use it if the user set config background cannot be loaded - if (settings.contains(QStringLiteral("background"))) { - insert(QStringLiteral("defaultBackground"), settings.value(QStringLiteral("background"))); - } - } - - QVariant ThemeConfig::value(const QString &key, const QVariant &def) { - if (!contains(key)) { - return def; - } - - return value(key); - } - - bool ThemeConfig::boolValue(const QString &key) { - return value(key).toBool(); - } - - int ThemeConfig::intValue(const QString &key) { - bool ok; - auto ret = value(key).toInt(&ok); - if (!ok) { - qWarning() << "Could not convert" << key << "(value" << value(key) << ") to int"; - } - return ret; - } - - qreal ThemeConfig::realValue(const QString &key) { - bool ok; - auto ret = value(key).toReal(&ok); - if (!ok) { - qWarning() << "Could not convert" << key << "(value" << value(key) << ") to real"; - } - return ret; - } - - QString ThemeConfig::stringValue(const QString &key) { - return value(key).toString(); - } -} diff --git a/src/common/ThemeConfig.h b/src/common/ThemeConfig.h deleted file mode 100644 index fa10b54..0000000 --- a/src/common/ThemeConfig.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2016 Pier Luigi Fiorini -* Copyright (c) 2013 Abdurrahman AVCI -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -#ifndef DDM_THEMECONFIG_H -#define DDM_THEMECONFIG_H - -#include - -namespace DDM { - class ThemeConfig : public QQmlPropertyMap { - Q_OBJECT - public: - explicit ThemeConfig(const QString &path, QObject *parent = nullptr); - - void setTo(const QString &path); - - // Also provide QVariantMap's value(key, default) method - using QQmlPropertyMap::value; - QVariant value(const QString &key, const QVariant &def); - - // QSettings::IniFormat returns string types for basic - // types. Let the theme request specific conversions. - Q_INVOKABLE bool boolValue(const QString &key); - Q_INVOKABLE int intValue(const QString &key); - Q_INVOKABLE qreal realValue(const QString &key); - Q_INVOKABLE QString stringValue(const QString &key); - }; -} - -#endif // DDM_THEMECONFIG_H diff --git a/src/common/ThemeMetadata.cpp b/src/common/ThemeMetadata.cpp deleted file mode 100644 index 38d4b9b..0000000 --- a/src/common/ThemeMetadata.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2016 Pier Luigi Fiorini -* Copyright (c) 2013 Abdurrahman AVCI -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -#include "ThemeMetadata.h" - -#include - -namespace DDM { - class ThemeMetadataPrivate { - public: - QString mainScript { QStringLiteral("Main.qml") }; - QString configFile; - QString translationsDirectory { QStringLiteral(".") }; - }; - - ThemeMetadata::ThemeMetadata(const QString &path, QObject *parent) : QObject(parent), d(new ThemeMetadataPrivate()) { - setTo(path); - } - - ThemeMetadata::~ThemeMetadata() { - delete d; - } - - const QString &ThemeMetadata::mainScript() const { - return d->mainScript; - } - - const QString &ThemeMetadata::configFile() const { - return d->configFile; - } - - const QString &ThemeMetadata::translationsDirectory() const { - return d->translationsDirectory; - } - - void ThemeMetadata::setTo(const QString &path) { - QSettings settings(path, QSettings::IniFormat); - // read values - d->mainScript = settings.value(QStringLiteral("SddmGreeterTheme/MainScript"), QStringLiteral("Main.qml")).toString(); - d->configFile = settings.value(QStringLiteral("SddmGreeterTheme/ConfigFile"), QStringLiteral("theme.conf")).toString(); - d->translationsDirectory = settings.value(QStringLiteral("SddmGreeterTheme/TranslationsDirectory"), QStringLiteral(".")).toString(); - } -} diff --git a/src/common/ThemeMetadata.h b/src/common/ThemeMetadata.h deleted file mode 100644 index 9a72962..0000000 --- a/src/common/ThemeMetadata.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2016 Pier Luigi Fiorini -* Copyright (c) 2013 Abdurrahman AVCI -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -#ifndef DDM_THEMEMETADATA_H -#define DDM_THEMEMETADATA_H - -#include - -namespace DDM { - class ThemeMetadataPrivate; - - class ThemeMetadata : public QObject { - Q_OBJECT - Q_DISABLE_COPY(ThemeMetadata) - public: - explicit ThemeMetadata(const QString &path, QObject *parent = 0); - ~ThemeMetadata(); - - const QString &mainScript() const; - const QString &configFile() const; - const QString &translationsDirectory() const; - - void setTo(const QString &path); - - private: - ThemeMetadataPrivate *d { nullptr }; - }; -} - -#endif // DDM_THEMEMETADATA_H diff --git a/src/daemon/Auth.cpp b/src/daemon/Auth.cpp index 673728f..7276eb5 100644 --- a/src/daemon/Auth.cpp +++ b/src/daemon/Auth.cpp @@ -29,88 +29,21 @@ #include namespace DDM { - int Auth::lastId = 0; - Auth::Auth(QObject *parent) - : QObject(parent) - , id(++lastId) - , m_pam(new Pam(this)) - , m_session(new UserSession(this)) { - connect(m_session, - QOverload::of(&QProcess::finished), - this, - &Auth::userProcessFinished); - } - - Auth::~Auth() { - stop(); - } - - bool Auth::authenticate(const QByteArray &secret) { - m_pam->user = user; - if (!m_pam->start()) { - utmpLogin(std::to_string(tty).c_str(), display, user, 0, false); - return false; - } - if (!skipAuth && !m_pam->authenticate(secret)) { - utmpLogin(std::to_string(tty).c_str(), display, user, 0, false); - return false; - } - active = true; - return true; - } - - int Auth::openSession(const QProcessEnvironment &env) { - Q_ASSERT(active); - auto ret = m_pam->openSession(env); - if (!ret.has_value()) - return -1; - m_env = *ret; - xdgSessionId = m_env.value(QStringLiteral("XDG_SESSION_ID")).toInt(); - return xdgSessionId; - } - - void Auth::startUserProcess(const QString &command, Display::DisplayServerType type, const QByteArray &cookie) { - Q_ASSERT(!m_env.isEmpty()); - QProcessEnvironment env = m_env; - struct passwd *pw = getpwnam(qPrintable(user)); - if (pw) { - env.insert(QStringLiteral("HOME"), QString::fromLocal8Bit(pw->pw_dir)); - env.insert(QStringLiteral("PWD"), QString::fromLocal8Bit(pw->pw_dir)); - env.insert(QStringLiteral("SHELL"), QString::fromLocal8Bit(pw->pw_shell)); - env.insert(QStringLiteral("USER"), QString::fromLocal8Bit(pw->pw_name)); - env.insert(QStringLiteral("LOGNAME"), QString::fromLocal8Bit(pw->pw_name)); - } - m_session->setProcessEnvironment(env); - m_session->start(command, type, cookie); - - // write successful login to utmp/wtmp - const QString displayId = env.value(QStringLiteral("DISPLAY")); - const QString vt = env.value(QStringLiteral("XDG_VTNR")); - // cache pid for session end - utmpLogin(vt, displayId, user, m_session->processId(), true); - } - - void Auth::stop() { - if (!active) - return; - active = false; - qint64 pid = m_session->processId(); - if (m_session->state() != QProcess::NotRunning) - m_session->stop(); - if (m_pam->sessionOpened) - m_pam->closeSession(); - - // write logout to utmp/wtmp - if (pid > 0) { - QProcessEnvironment env = m_session->processEnvironment(); - QString vt = env.value(QStringLiteral("XDG_VTNR")); - QString displayId = env.value(QStringLiteral("DISPLAY")); - utmpLogout(vt, displayId, pid); - } - } - - void Auth::utmpLogin(const QString &vt, const QString &displayName, const QString &user, qint64 pid, bool authSuccessful) { + ////////////////////// + // Helper functions // + ////////////////////// + + /** + * Write utmp/wtmp/btmp records when a user logs in + * + * @param vt Virtual terminal (tty7, tty8,...) + * @param displayName Display (:0, :1,...) + * @param user User logging in + * @param pid User process ID (e.g. PID of startkde) + * @param authSuccessful Was authentication successful + */ + static void utmpLogin(const QString &vt, const QString &displayName, const QString &user, qint64 pid, bool authSuccessful) { struct utmpx entry { }; struct timeval tv; @@ -155,7 +88,14 @@ namespace DDM { } } - void Auth::utmpLogout(const QString &vt, const QString &displayName, qint64 pid) { + /** + * Write utmp/wtmp records when a user logs out + * + * @param vt Virtual terminal (tty7, tty8,...) + * @param displayName Display (:0, :1,...) + * @param pid User process ID (e.g. PID of startkde) + */ + static void utmpLogout(const QString &vt, const QString &displayName, qint64 pid) { struct utmpx entry { }; struct timeval tv; @@ -189,4 +129,87 @@ namespace DDM { // append to wtmp updwtmpx("/var/log/wtmp", &entry); } + + ///////////////////////// + // Auth implementation // + ///////////////////////// + + Auth::Auth(QObject *parent, QString user) + : QObject(parent) + , user(user) + , m_pam(new Pam(this)) + , m_session(new UserSession(this)) { + connect(m_session, + QOverload::of(&QProcess::finished), + this, + &Auth::userProcessFinished); + } + + Auth::~Auth() { + stop(); + } + + bool Auth::authenticate(const QByteArray &secret) { + m_pam->user = user; + if (!m_pam->start()) { + utmpLogin(std::to_string(tty).c_str(), display, user, 0, false); + return false; + } + if (!m_pam->authenticate(secret)) { + utmpLogin(std::to_string(tty).c_str(), display, user, 0, false); + return false; + } + active = true; + return true; + } + + int Auth::openSession(const QProcessEnvironment &env) { + Q_ASSERT(active); + auto ret = m_pam->openSession(env); + if (!ret.has_value()) + return -1; + m_env = *ret; + xdgSessionId = m_env.value(QStringLiteral("XDG_SESSION_ID")).toInt(); + return xdgSessionId; + } + + void Auth::startUserProcess(const QString &command, const QByteArray &cookie) { + Q_ASSERT(!m_env.isEmpty()); + QProcessEnvironment env = m_env; + struct passwd *pw = getpwnam(qPrintable(user)); + if (pw) { + env.insert(QStringLiteral("HOME"), QString::fromLocal8Bit(pw->pw_dir)); + env.insert(QStringLiteral("PWD"), QString::fromLocal8Bit(pw->pw_dir)); + env.insert(QStringLiteral("SHELL"), QString::fromLocal8Bit(pw->pw_shell)); + env.insert(QStringLiteral("USER"), QString::fromLocal8Bit(pw->pw_name)); + env.insert(QStringLiteral("LOGNAME"), QString::fromLocal8Bit(pw->pw_name)); + } + m_session->setProcessEnvironment(env); + m_session->start(command, type, cookie); + + // write successful login to utmp/wtmp + const QString displayId = env.value(QStringLiteral("DISPLAY")); + const QString vt = env.value(QStringLiteral("XDG_VTNR")); + // cache pid for session end + utmpLogin(vt, displayId, user, m_session->processId(), true); + } + + void Auth::stop() { + if (!active) + return; + active = false; + qint64 pid = m_session->processId(); + if (m_session->state() != QProcess::NotRunning) + m_session->stop(); + if (m_pam->sessionOpened) + m_pam->closeSession(); + + // write logout to utmp/wtmp + if (pid > 0) { + QProcessEnvironment env = m_session->processEnvironment(); + QString vt = env.value(QStringLiteral("XDG_VTNR")); + QString displayId = env.value(QStringLiteral("DISPLAY")); + utmpLogout(vt, displayId, pid); + } + } } // namespace DDM diff --git a/src/daemon/Auth.h b/src/daemon/Auth.h index 844a8af..e32393a 100644 --- a/src/daemon/Auth.h +++ b/src/daemon/Auth.h @@ -30,71 +30,87 @@ namespace DDM { class Pam; class UserSession; + /** Authentication handler, manage login and session */ class Auth : public QObject { Q_OBJECT public: - Auth(QObject *parent); + Auth(QObject *parent, QString user); ~Auth(); + /** Indicates whether the Auth is active (PAM module started) */ bool active{ false }; + + /** Username. Must be set before authenticate() */ QString user{}; - QByteArray cookie{}; - bool singleMode{ false }; - bool skipAuth{ false }; - - int id{ 0 }; - static int lastId; + + /** Display sever type of the session. Must be set before startUserProcess() */ + Display::DisplayServerType type{}; + + /** The "Session ID" (defined and used by DisplayManager) */ QString sessionId{}; + + /** X Display identifier (e.g. :0), if presents */ QString display{}; + + /** Virtual terminal number (e.g. 7 for tty7) */ int tty{ 0 }; + + /** Logind session ID (the XDG_SESSION_ID env var) */ int xdgSessionId{ 0 }; + public Q_SLOTS: /** - * Sets up the environment and starts the authentication - */ + * Sets up the environment and starts the authentication. + * + * @param secret Password or other secret data acceptable by PAM + * @return true on success, false on failure + */ bool authenticate(const QByteArray &secret); + /** + * Opens user session via PAM and returns the XDG_SESSION_ID. + * Must be called after authenticate(). + * + * @param env Environment variables to set for the session + * @return XDG_SESSION_ID on success, -1 on failure + */ int openSession(const QProcessEnvironment &env); - void startUserProcess(const QString &command, - Display::DisplayServerType type, - const QByteArray &cookie = QByteArray()); + /** + * Starts process inside opened session. + * Must be called after openSession(). + * Only 1 process can be started per Auth instance, + * userProcessFinished() is emitted when the process ends. + * Implemented in UserSession. + * + * @param command Command to exec + * @param cookie XAuth cookie (must be set for X11) + */ + void startUserProcess(const QString &command, const QByteArray &cookie = QByteArray()); /** - * Indicates that we do not need the process anymore. + * Stop PAM, close opened session and end up user process. + * This will be automatically called in the destructor. */ void stop(); Q_SIGNALS: /** - * Emitted when the session ends. + * Emitted when the user process ends. * - * @param success true if every underlying task went fine + * @param status Exit code of the user process */ void userProcessFinished(int status); private: - Pam *m_pam { nullptr }; - UserSession *m_session{ nullptr }; - QProcessEnvironment m_env{}; + /** The PAM module */ + Pam *m_pam{ nullptr }; - /** - * Write utmp/wtmp/btmp records when a user logs in - * @param vt Virtual terminal (tty7, tty8,...) - * @param displayName Display (:0, :1,...) - * @param user User logging in - * @param pid User process ID (e.g. PID of startkde) - * @param authSuccessful Was authentication successful - */ - void utmpLogin(const QString &vt, const QString &displayName, const QString &user, qint64 pid, bool authSuccessful); + /** The user process */ + UserSession *m_session{ nullptr }; - /** - * Write utmp/wtmp records when a user logs out - * @param vt Virtual terminal (tty7, tty8,...) - * @param displayName Display (:0, :1,...) - * @param pid User process ID (e.g. PID of startkde) - */ - void utmpLogout(const QString &vt, const QString &displayName, qint64 pid); + /** Cached environment inside the opened logind session, for the user process */ + QProcessEnvironment m_env{}; }; } diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 885c12f..bff56f0 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -1,6 +1,5 @@ include_directories( ${LIBXAU_INCLUDE_DIRS} - "${LIBXCB_INCLUDE_DIR}" ) pkg_search_module(WAYLAND REQUIRED IMPORTED_TARGET wayland-client) @@ -31,7 +30,6 @@ set(DAEMON_SOURCES DisplayManager.cpp Pam.cpp PowerManager.cpp - Seat.cpp SeatManager.cpp SocketServer.cpp TreelandConnector.cpp @@ -74,7 +72,6 @@ target_link_libraries(ddm Qt${QT_MAJOR_VERSION}::DBus Qt${QT_MAJOR_VERSION}::Network Qt${QT_MAJOR_VERSION}::Qml - ${LIBXCB_LIBRARIES} ${PAM_LIBRARIES} PkgConfig::WAYLAND ) diff --git a/src/daemon/DaemonApp.cpp b/src/daemon/DaemonApp.cpp index 161fef9..2edacf7 100644 --- a/src/daemon/DaemonApp.cpp +++ b/src/daemon/DaemonApp.cpp @@ -49,9 +49,6 @@ namespace DDM { // log message qDebug() << "Initializing..."; - // set testing parameter - m_testing = (arguments().indexOf(QStringLiteral("--test-mode")) != -1); - bool consoleKitServiceActivatable = false; QDBusReply activatableNamesReply = QDBusConnection::systemBus().interface()->activatableServiceNames(); if (activatableNamesReply.isValid()) { @@ -95,11 +92,6 @@ namespace DDM { m_seatManager->initialize(); } - bool DaemonApp::testing() const { - return m_testing; - } - - QString DaemonApp::hostName() const { return QHostInfo::localHostName(); } @@ -143,7 +135,6 @@ int main(int argc, char **argv) { if (arguments.contains(QStringLiteral("--help")) || arguments.contains(QStringLiteral("-h"))) { std::cout << "Usage: ddm [options]\n" << "Options: \n" - << " --test-mode Start daemon in test mode" << std::endl << " --example-config Print the complete current configuration to stdout" << std::endl; return EXIT_FAILURE; diff --git a/src/daemon/DaemonApp.h b/src/daemon/DaemonApp.h index c5620f7..5badd5e 100644 --- a/src/daemon/DaemonApp.h +++ b/src/daemon/DaemonApp.h @@ -40,10 +40,6 @@ namespace DDM { static DaemonApp *instance() { return self; } - // TODO: move these two away - bool testing() const; - bool first { true }; - QString hostName() const; DisplayManager *displayManager() const; PowerManager *powerManager() const; @@ -61,7 +57,6 @@ namespace DDM { int m_lastSessionId { 0 }; - bool m_testing { false }; DisplayManager *m_displayManager { nullptr }; PowerManager *m_powerManager { nullptr }; SeatManager *m_seatManager { nullptr }; diff --git a/src/daemon/Display.cpp b/src/daemon/Display.cpp index 54d452c..fb81819 100644 --- a/src/daemon/Display.cpp +++ b/src/daemon/Display.cpp @@ -27,10 +27,11 @@ #include "DisplayManager.h" #include "XorgDisplayServer.h" #include "TreelandDisplayServer.h" -#include "Seat.h" +#include "SeatManager.h" #include "SocketServer.h" #include "Messages.h" #include "SocketWriter.h" +#include "TreelandConnector.h" #include #include @@ -88,9 +89,9 @@ namespace DDM { return VirtualTerminal::setUpNewVt(); } - Display::Display(Seat *parent) + Display::Display(SeatManager *parent, QString name) : QObject(parent) - , seat(parent) + , name(name) , m_socketServer(new SocketServer(this)) { // Create display server @@ -101,7 +102,7 @@ namespace DDM { // Record current VT as ddm user session DaemonApp::instance()->displayManager()->AddSession( {}, - seat->name(), + name, "ddm", static_cast(VirtualTerminal::currentVt())); @@ -123,20 +124,20 @@ namespace DDM { } Display::~Display() { - for (auto *item : m_auths) + for (auto *item : std::as_const(auths)) disconnect(item, &Auth::userProcessFinished, this, &Display::userProcessFinished); stop(); } - void Display::switchToUser(const QString &user, int xdgSessionId) { - if (xdgSessionId <= 0) { - qFatal() << "Invalid xdg session id" << xdgSessionId << "for user" << user; + void Display::activateSession(const QString &user, int xdgSessionId) { + if (xdgSessionId <= 0 && user != QStringLiteral("ddm")) { + qCritical() << "Invalid xdg session id" << xdgSessionId << "for user" << user; return; } m_treeland->activateUser(user, xdgSessionId); - if (Logind::isAvailable()) { + if (xdgSessionId > 0 && Logind::isAvailable()) { OrgFreedesktopLogin1ManagerInterface manager(Logind::serviceName(), Logind::managerPath(), QDBusConnection::systemBus()); manager.ActivateSession(QString::number(xdgSessionId)); } @@ -172,9 +173,8 @@ namespace DDM { if (!m_started) return; - for (auto *item : m_auths) { + for (auto *item : std::as_const(auths)) item->stop(); - } // stop socket server m_socketServer->stop(); @@ -193,10 +193,9 @@ namespace DDM { } void Display::connected(QLocalSocket *socket) { - m_socket = socket; - // send logined user (for possible crash recovery) + // send logged in users (for possible crash recovery) SocketWriter writer(socket); - for (Auth *auth : m_auths) { + for (Auth *auth : std::as_const(auths)) { if (auth->active) writer << quint32(DaemonMessages::UserLoggedIn) << auth->user << auth->xdgSessionId; } @@ -205,71 +204,14 @@ namespace DDM { void Display::login(QLocalSocket *socket, const QString &user, const QString &password, const Session &session) { - m_socket = socket; - - //the DDM user has special privileges that skip password checking so that we can load the greeter - //block ever trying to log in as the DDM user - if (user == QLatin1String("dde")) { - emit loginFailed(m_socket, user); - return; - } - - // authenticate - startAuth(user, password, session); - } - - void Display::logout([[maybe_unused]] QLocalSocket *socket, int id) { - OrgFreedesktopLogin1ManagerInterface manager(Logind::serviceName(), Logind::managerPath(), QDBusConnection::systemBus()); - manager.TerminateSession(QString::number(id)); - } - - void Display::unlock(QLocalSocket *socket, - const QString &user, const QString &password) { - m_socket = socket; - - //the DDM user has special privileges that skip password checking so that we can load the greeter - //block ever trying to log in as the DDM user if (user == QLatin1String("dde")) { - emit loginFailed(m_socket, user); + emit loginFailed(socket, user); return; } - // authenticate - startIdentify(user, password); - } - - void Display::startIdentify(const QString &user, const QString &password) { - qDebug() << "start Identify user" << user; - Auth auth(this); - auth.setObjectName("userIdentify"); - - auth.user = user; - if (auth.authenticate(password.toLocal8Bit())) { - DaemonApp::instance()->displayManager()->setLastActivatedUser(user); - if (mainConfig.Users.RememberLastUser.get()) - stateConfig.Last.User.set(user); - else - stateConfig.Last.User.setDefault(); - stateConfig.save(); - - m_treeland->onLoginSucceeded(user); - // TODO: Use exact ID when there're multiple sessions for a user - int xdgSessionId = 0; - for (auto *auth : std::as_const(m_auths)) { - if (auth->user == user && auth->xdgSessionId > 0) { - xdgSessionId = auth->xdgSessionId; - break; - } - } - switchToUser(user, xdgSessionId); - } - } - - void Display::startAuth(const QString &user, const QString &password, const Session &session) { - - // respond to authentication requests + // Get Auth object Auth *auth = nullptr; - for (auto *item : m_auths) { + for (auto *item : std::as_const(auths)) { if (item->user == user) { auth = item; break; @@ -277,7 +219,7 @@ namespace DDM { } if (!auth) - auth = new Auth(this); + auth = new Auth(this, user); if (auth->active) { qWarning() << "Existing authentication ongoing, aborting"; @@ -298,19 +240,23 @@ namespace DDM { return; } + // Run password check auth->user = user; - auth->tty = terminalId; - auth->singleMode = session.isSingleMode(); - if (!auth->authenticate(password.toLocal8Bit())) + if (session.isSingleMode()) + auth->tty = VirtualTerminal::setUpNewVt(); + else + auth->tty = terminalId; + if (!auth->authenticate(password.toLocal8Bit())) { + Q_EMIT loginFailed(socket, user); return; + } // some information qDebug() << "Session" << session.fileName() << "selected, command:" << session.exec() << "for VT" << auth->tty; - DaemonApp::instance()->displayManager()->setLastActivatedUser(user); - // save last user and last session + DaemonApp::instance()->displayManager()->setLastActivatedUser(user); if (mainConfig.Users.RememberLastUser.get()) stateConfig.Last.User.set(auth->user); else @@ -321,12 +267,13 @@ namespace DDM { stateConfig.Last.Session.setDefault(); stateConfig.save(); + // Prepare session environment QProcessEnvironment env; env.insert(session.additionalEnv()); // session id const QString sessionId = QStringLiteral("Session%1").arg(daemonApp->newSessionId()); - daemonApp->displayManager()->AddSession(sessionId, seat->name(), user, auth->tty); + daemonApp->displayManager()->AddSession(sessionId, name, user, auth->tty); daemonApp->displayManager()->setLastSession(sessionId); env.insert(QStringLiteral("XDG_SESSION_PATH"), daemonApp->displayManager()->sessionPath(sessionId)); auth->sessionId = sessionId; @@ -338,23 +285,26 @@ namespace DDM { env.insert(QStringLiteral("XDG_SESSION_CLASS"), QStringLiteral("user")); env.insert(QStringLiteral("XDG_SESSION_TYPE"), session.xdgSessionType()); env.insert(QStringLiteral("XDG_VTNR"), QString::number(auth->tty)); - env.insert(QStringLiteral("XDG_SEAT"), seat->name()); - env.insert(QStringLiteral("XDG_SEAT_PATH"), daemonApp->displayManager()->seatPath(seat->name())); + env.insert(QStringLiteral("XDG_SEAT"), name); + env.insert(QStringLiteral("XDG_SEAT_PATH"), daemonApp->displayManager()->seatPath(name)); env.insert(QStringLiteral("XDG_SESSION_DESKTOP"), session.desktopNames()); - DisplayServerType type; + // Special preparation for each display server type + // + // TODO: Let Treeland drop DRM master when inactive, so that X + // server and other Wayland compositor can co-exist with + // greeter (the Treeland) QByteArray cookie; if (session.isSingleMode()) { - type = Treeland; + auth->type = Treeland; env.insert("DDE_CURRENT_COMPOSITOR", "TreeLand"); - m_treeland->onLoginSucceeded(user); } else if (session.xdgSessionType() == QLatin1String("x11")) { - type = X11; + auth->type = X11; - // stop treeland m_treeland->stop(); - sleep(1); // give some time to treeland to stop before starting Xorg + QThread::msleep(500); // give some time to treeland to stop properly + // Start X server m_x11Server = new XorgDisplayServer(this); connect(m_x11Server, &XorgDisplayServer::stopped, this, &Display::stop); if (!m_x11Server->start(auth->tty)) { @@ -365,25 +315,81 @@ namespace DDM { env.insert(QStringLiteral("DISPLAY"), m_x11Server->display); cookie = m_x11Server->cookie(); } else { - type = Wayland; - // stop treeland + auth->type = Wayland; + m_treeland->stop(); - sleep(1); // give some time to treeland to stop before starting Wayland session + QThread::msleep(500); // give some time to treeland to stop properly } + // Open Logind session int xdgSessionId = auth->openSession(env); if (xdgSessionId <= 0) { auth->stop(); delete auth; return; } - if (type == Treeland) - switchToUser(auth->user, xdgSessionId); + if (auth->type == Treeland) { + Q_EMIT loginSucceeded(socket, user); + // Tell Treeland to enter the session + activateSession(auth->user, xdgSessionId); + } + // Exec the desktop process connect(auth, &Auth::userProcessFinished, this, &Display::userProcessFinished); - auth->startUserProcess(session.exec(), type, cookie); + auth->startUserProcess(session.exec(), cookie); + + // The user process is ongoing, append to active auths + // The auth will be delete later in userProcessFinished() + auths << auth; + } + + void Display::logout([[maybe_unused]] QLocalSocket *socket, int id) { + OrgFreedesktopLogin1ManagerInterface manager(Logind::serviceName(), Logind::managerPath(), QDBusConnection::systemBus()); + manager.TerminateSession(QString::number(id)); + } + + void Display::unlock(QLocalSocket *socket, const QString &user, const QString &password) { + if (user == QLatin1String("dde")) { + emit loginFailed(socket, user); + return; + } + + qDebug() << "Start identify user" << user; - m_auths << auth; + // Only run password check + // + // No user process execution, so the auth can be thrown away + // immediately after use + Auth auth(this, user); + auth.user = user; + if (!auth.authenticate(password.toLocal8Bit())) { + Q_EMIT loginFailed(socket, user); + return; + } + + // Save last user + DaemonApp::instance()->displayManager()->setLastActivatedUser(user); + if (mainConfig.Users.RememberLastUser.get()) + stateConfig.Last.User.set(user); + else + stateConfig.Last.User.setDefault(); + stateConfig.save(); + + // Find the auth that started the session, which contains full informations + for (auto *auth : std::as_const(auths)) { + if (auth->user == user && auth->xdgSessionId > 0) { + if (auth->type == Treeland) { + // TODO: Use exact ID when there're multiple sessions for a user + // TODO: Jump to auth->tty + Q_EMIT loginSucceeded(socket, user); + activateSession(user, auth->xdgSessionId); + } else { + VirtualTerminal::jumpToVt(auth->tty, false); + } + return; + } + } + Q_EMIT loginFailed(socket, user); } void Display::userProcessFinished([[maybe_unused]] int status) { @@ -391,10 +397,9 @@ namespace DDM { daemonApp->displayManager()->RemoveSession(auth->sessionId); - m_auths.removeOne(auth); + auths.removeAll(auth); delete auth; - // TODO: switch to greeter - m_treeland->activateUser("dde", 0); + activateSession("dde", 0); } } diff --git a/src/daemon/Display.h b/src/daemon/Display.h index b052fb2..2fdb5d5 100644 --- a/src/daemon/Display.h +++ b/src/daemon/Display.h @@ -34,9 +34,10 @@ namespace DDM { class Auth; class XorgDisplayServer; class TreelandDisplayServer; - class Seat; + class SeatManager; class SocketServer; + /** Class represents a display (seat) */ class Display : public QObject { Q_OBJECT Q_DISABLE_COPY(Display) @@ -48,18 +49,55 @@ namespace DDM { }; Q_ENUM(DisplayServerType) - explicit Display(Seat *parent); + /** + * Constructor + * + * @param parent The SeatManager + * @param name Seat name + */ + explicit Display(SeatManager *parent, QString name); + ~Display(); - void switchToUser(const QString &user, int xdgSessionId); + /** + * Tell Treeland to activate a certain session. + * + * Called with user = "dde" and xdgSessionId <= 0 + * will send Treeland into lockscreen. + * + * @param user Username + * @param xdgSessionId Logind session ID + */ + void activateSession(const QString &user, int xdgSessionId); + + /** Seat name */ + QString name{}; + + /** VT number of the greeter */ + int terminalId{ 0 }; - Seat *seat{ nullptr }; - int terminalId = 0; + /** List of active authentications */ + QList auths; public slots: + /** + * Start the display. + * This will start Treeland and show greeter. + * + * @return true on success, false on failure + */ bool start(); + + /** + * Stop the display. + * Will be called automatically when destructed. + */ void stop(); + /////////////////////////////////////////////////// + // Slots for socket to communicate with Treeland // + /////////////////////////////////////////////////// + void connected(QLocalSocket *socket); void login(QLocalSocket *socket, const QString &user, const QString &password, @@ -70,22 +108,28 @@ namespace DDM { const QString &user, const QString &password); signals: + /** Emitted when stop() */ void stopped(); + ///////////////////////////////////////////////////// + // Signals for socket to communicate with Treeland // + ///////////////////////////////////////////////////// + void loginFailed(QLocalSocket *socket, const QString &user); void loginSucceeded(QLocalSocket *socket, const QString &user); private: - void startAuth(const QString &user, const QString &password, - const Session &session); - void startIdentify(const QString &user, const QString &password); - + /** Indicates whether the display is started */ bool m_started{ false }; - QVector m_auths; + + /** Treeland display server */ TreelandDisplayServer *m_treeland{ nullptr }; + + /** X11 display server, if started */ XorgDisplayServer *m_x11Server{ nullptr }; + + /** Socket server for communication with Treeland */ SocketServer *m_socketServer { nullptr }; - QPointer m_socket; private slots: void userProcessFinished(int status); diff --git a/src/daemon/DisplayManager.cpp b/src/daemon/DisplayManager.cpp index 2cf3c0a..9032c9f 100644 --- a/src/daemon/DisplayManager.cpp +++ b/src/daemon/DisplayManager.cpp @@ -26,7 +26,6 @@ #include "displaymanageradaptor.h" #include "seatadaptor.h" #include "sessionadaptor.h" -#include "VirtualTerminal.h" const QString DISPLAYMANAGER_SERVICE = QStringLiteral("org.freedesktop.DisplayManager"); const QString DISPLAYMANAGER_PATH = QStringLiteral("/org/freedesktop/DisplayManager"); @@ -40,7 +39,7 @@ namespace DDM { new DDMDisplayManagerAdaptor(this); // register object - QDBusConnection connection = (daemonApp->testing()) ? QDBusConnection::sessionBus() : QDBusConnection::systemBus(); + QDBusConnection connection = QDBusConnection::systemBus(); connection.registerService(DISPLAYMANAGER_SERVICE); connection.registerObject(DISPLAYMANAGER_PATH, this); @@ -193,7 +192,7 @@ namespace DDM { new SeatAdaptor(this); // register object - QDBusConnection connection = (daemonApp->testing()) ? QDBusConnection::sessionBus() : QDBusConnection::systemBus(); + QDBusConnection connection = QDBusConnection::systemBus(); connection.registerService(DISPLAYMANAGER_SERVICE); connection.registerObject(m_path, this); } @@ -232,7 +231,7 @@ namespace DDM { new SessionAdaptor(this); // register object - QDBusConnection connection = (daemonApp->testing()) ? QDBusConnection::sessionBus() : QDBusConnection::systemBus(); + QDBusConnection connection = QDBusConnection::systemBus(); connection.registerService(DISPLAYMANAGER_SERVICE); connection.registerObject(m_path, this); } diff --git a/src/daemon/PowerManager.cpp b/src/daemon/PowerManager.cpp index df96758..0686378 100644 --- a/src/daemon/PowerManager.cpp +++ b/src/daemon/PowerManager.cpp @@ -174,8 +174,7 @@ const QString CK2_OBJECT = QStringLiteral("org.freedesktop.ConsoleKit.Manager"); } void reboot() const { - if (!daemonApp->testing()) - m_interface->call(QStringLiteral("Reboot"), true); + m_interface->call(QStringLiteral("Reboot"), true); } void suspend() const { @@ -228,9 +227,6 @@ const QString CK2_OBJECT = QStringLiteral("org.freedesktop.ConsoleKit.Manager"); } void PowerManager::powerOff() const { - if (daemonApp->testing()) - return; - for (PowerManagerBackend *backend: m_backends) { if (backend->capabilities() & Capability::PowerOff) { backend->powerOff(); @@ -240,9 +236,6 @@ const QString CK2_OBJECT = QStringLiteral("org.freedesktop.ConsoleKit.Manager"); } void PowerManager::reboot() const { - if (daemonApp->testing()) - return; - for (PowerManagerBackend *backend: m_backends) { if (backend->capabilities() & Capability::Reboot) { backend->reboot(); @@ -252,9 +245,6 @@ const QString CK2_OBJECT = QStringLiteral("org.freedesktop.ConsoleKit.Manager"); } void PowerManager::suspend() const { - if (daemonApp->testing()) - return; - for (PowerManagerBackend *backend: m_backends) { if (backend->capabilities() & Capability::Suspend) { backend->suspend(); @@ -264,9 +254,6 @@ const QString CK2_OBJECT = QStringLiteral("org.freedesktop.ConsoleKit.Manager"); } void PowerManager::hibernate() const { - if (daemonApp->testing()) - return; - for (PowerManagerBackend *backend: m_backends) { if (backend->capabilities() & Capability::Hibernate) { backend->hibernate(); @@ -276,9 +263,6 @@ const QString CK2_OBJECT = QStringLiteral("org.freedesktop.ConsoleKit.Manager"); } void PowerManager::hybridSleep() const { - if (daemonApp->testing()) - return; - for (PowerManagerBackend *backend: m_backends) { if (backend->capabilities() & Capability::HybridSleep) { backend->hybridSleep(); diff --git a/src/daemon/Seat.cpp b/src/daemon/Seat.cpp deleted file mode 100644 index ecd86df..0000000 --- a/src/daemon/Seat.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2014 Pier Luigi Fiorini -* Copyright (c) 2013 Abdurrahman AVCI -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -#include "Seat.h" - -#include "Configuration.h" -#include "DaemonApp.h" -#include "Display.h" -#include "XorgDisplayServer.h" -#include "VirtualTerminal.h" - -#include -#include -#include - -#include -#include -#include -#include - -namespace DDM { - Seat::Seat(const QString &name, QObject *parent) : QObject(parent), m_name(name) { - createDisplay(); - } - - const QString &Seat::name() const { - return m_name; - } - - void Seat::createDisplay() { - //reload config if needed - mainConfig.load(); - - if (!m_displays.isEmpty()) { - auto display = m_displays.first(); - display->switchToUser("dde", 0); - return; - } - - // create a new display - qDebug() << "Adding new display..."; - Display *display = new Display(this); - - // restart display on stop - connect(display, &Display::stopped, this, &Seat::displayStopped); - - // add display to the list - m_displays << display; - - // start the display - startDisplay(display); - } - - void Seat::startDisplay(Display *display, int tryNr) { - if (display->start()) - return; - - // It's possible that the system isn't ready yet (driver not loaded, - // device not enumerated, ...). It's not possible to tell when that changes, - // so try a few times with a delay in between. - qWarning() << "Attempt" << tryNr << "starting the Display server on vt" << display->terminalId << "failed"; - - if(tryNr >= 3) { - qCritical() << "Could not start Display server on vt" << display->terminalId; - return; - } - - QTimer::singleShot(2000, display, [this, display, tryNr] { startDisplay(display, tryNr + 1); }); - } - - void Seat::removeDisplay(Display* display) { - qDebug() << "Removing display" << display << "..."; - - - // remove display from list - m_displays.removeAll(display); - - // stop the display - display->blockSignals(true); - display->stop(); - display->blockSignals(false); - - // delete display - display->deleteLater(); - } - - void Seat::displayStopped() { - Display *display = qobject_cast(sender()); - OrgFreedesktopLogin1ManagerInterface manager(Logind::serviceName(), Logind::managerPath(), QDBusConnection::systemBus()); - std::optional nextVt; - - // remove display - removeDisplay(display); - - // restart otherwise - if (m_displays.isEmpty()) { - createDisplay(); - } - // If there is still a session running on some display, - // switch to last display in display vector. - // Set vt_auto to true, so let the kernel handle the - // vt switch automatically (VT_AUTO). - else if (!nextVt) { - int disp = m_displays.last()->terminalId; - if (disp != -1) - nextVt = disp; - } - - if (nextVt) { - VirtualTerminal::jumpToVt(*nextVt, true); - } - } -} diff --git a/src/daemon/Seat.h b/src/daemon/Seat.h deleted file mode 100644 index a631b8c..0000000 --- a/src/daemon/Seat.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2013 Abdurrahman AVCI -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -#ifndef DDM_SEAT_H -#define DDM_SEAT_H - -#include -#include -#include "Display.h" - -namespace DDM { - class Display; - - class Seat : public QObject { - Q_OBJECT - Q_DISABLE_COPY(Seat) - public: - explicit Seat(const QString &name, QObject *parent = 0); - - const QString &name() const; - void createDisplay(); - - public slots: - void removeDisplay(DDM::Display* display); - - private slots: - void displayStopped(); - - private: - void startDisplay(DDM::Display *display, int tryNr = 1); - - QString m_name; - - QVector m_displays; - }; -} - -#endif // DDM_SEAT_H diff --git a/src/daemon/SeatManager.cpp b/src/daemon/SeatManager.cpp index 62dd054..867e775 100644 --- a/src/daemon/SeatManager.cpp +++ b/src/daemon/SeatManager.cpp @@ -19,15 +19,18 @@ #include "SeatManager.h" +#include "Configuration.h" #include "DaemonApp.h" -#include "Seat.h" +#include "Display.h" #include #include #include #include +#include #include "LogindDBusTypes.h" +#include namespace DDM { @@ -94,7 +97,7 @@ namespace DDM { } void SeatManager::initialize() { - if (DaemonApp::instance()->testing() || !Logind::isAvailable()) { + if (!Logind::isAvailable()) { //if we don't have logind/CK2, just create a single seat immediately and don't do any other connections createSeat(QStringLiteral("seat0")); return; @@ -118,41 +121,80 @@ namespace DDM { } void SeatManager::createSeat(const QString &name) { - // create a seat - Seat *seat = new Seat(name, this); + //reload config if needed + mainConfig.load(); + + // create a new display + qDebug() << "Adding new display..."; + Display *display = new Display(this, name); + + // restart display on stop + connect(display, &Display::stopped, this, &SeatManager::displayStopped); + + // start the display + startDisplay(display); // add to the list - m_seats.insert(name, seat); + displays.append(display); // emit signal emit seatCreated(name); } void SeatManager::removeSeat(const QString &name) { - // check if seat exists - if (!m_seats.contains(name)) - return; + for (auto display : std::as_const(displays)) { + if (display->name == name) { + // remove from the list + displays.removeAll(display); + // stop the display + display->blockSignals(true); + display->stop(); + display->blockSignals(false); + // delete display + display->deleteLater(); + // emit signal + emit seatRemoved(name); + return; + } + } + } - // remove from the list - Seat *seat = m_seats.take(name); + void SeatManager::switchToGreeter(const QString &name) { + for (auto display : std::as_const(displays)) { + if (display->name == name) { + // switch to greeter + display->activateSession("ddm", 0); + return; + } + } + } - // delete seat - seat->deleteLater(); + void SeatManager::startDisplay(Display *display, int tryNr) { + if (display->start()) + return; - // emit signal - emit seatRemoved(name); - } + // It's possible that the system isn't ready yet (driver not loaded, + // device not enumerated, ...). It's not possible to tell when that changes, + // so try a few times with a delay in between. + qWarning() << "Attempt" << tryNr << "starting the Display server on vt" << display->terminalId << "failed"; - void SeatManager::switchToGreeter(const QString &name) { - // check if seat exists - if (!m_seats.contains(name)) + if(tryNr >= 3) { + qCritical() << "Could not start Display server on vt" << display->terminalId; return; + } - // switch to greeter - m_seats.value(name)->createDisplay(); + QTimer::singleShot(2000, display, [this, display, tryNr] { startDisplay(display, tryNr + 1); }); + } + + void SeatManager::displayStopped() { + Display *display = qobject_cast(sender()); + QString name = display->name; + // re-create display + removeSeat(name); + createSeat(name); } - void DDM::SeatManager::logindSeatAdded(const QString& name, const QDBusObjectPath& objectPath) + void SeatManager::logindSeatAdded(const QString& name, const QDBusObjectPath& objectPath) { auto logindSeat = new LogindSeat(name, objectPath); connect(logindSeat, &LogindSeat::canGraphicalChanged, this, [this, logindSeat]() { @@ -163,13 +205,13 @@ namespace DDM { } }); - m_systemSeats.insert(name, logindSeat); + systemSeats.insert(name, logindSeat); } - void DDM::SeatManager::logindSeatRemoved(const QString& name, const QDBusObjectPath& objectPath) + void SeatManager::logindSeatRemoved(const QString& name, const QDBusObjectPath& objectPath) { Q_UNUSED(objectPath); - auto logindSeat = m_systemSeats.take(name); + auto logindSeat = systemSeats.take(name); delete logindSeat; removeSeat(name); } diff --git a/src/daemon/SeatManager.h b/src/daemon/SeatManager.h index eafa096..8d99a69 100644 --- a/src/daemon/SeatManager.h +++ b/src/daemon/SeatManager.h @@ -23,9 +23,9 @@ #include #include #include +#include "Display.h" namespace DDM { - class Seat; class LogindSeat; class SeatManager : public QObject { @@ -38,6 +38,9 @@ namespace DDM { void removeSeat(const QString &name); void switchToGreeter(const QString &seat); + QList displays; //these will exist only for graphical seats + QHash systemSeats; //these will exist for all seats + Q_SIGNALS: void seatCreated(const QString &name); void seatRemoved(const QString &name); @@ -45,10 +48,10 @@ namespace DDM { private Q_SLOTS: void logindSeatAdded(const QString &name, const QDBusObjectPath &objectPath); void logindSeatRemoved(const QString &name, const QDBusObjectPath &objectPath); + void displayStopped(); private: - QHash m_seats; //these will exist only for graphical seats - QHash m_systemSeats; //these will exist for all seats + void startDisplay(Display *display, int tryNr = 1); }; } diff --git a/src/daemon/TreelandConnector.cpp b/src/daemon/TreelandConnector.cpp index 351dfac..7414890 100644 --- a/src/daemon/TreelandConnector.cpp +++ b/src/daemon/TreelandConnector.cpp @@ -2,8 +2,11 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "TreelandConnector.h" +#include "Auth.h" #include "DaemonApp.h" +#include "Display.h" #include "DisplayManager.h" +#include "SeatManager.h" #include "VirtualTerminal.h" #include "treeland-ddm-v1.h" @@ -28,6 +31,17 @@ namespace DDM { static const char *defaultVtPath = "/dev/tty0"; +static bool isVtRunningTreeland(int vtnr) { + for (Display *display : daemonApp->seatManager()->displays) { + if (display->terminalId == vtnr) + return true; + for (Auth *auth : display->auths) + if (auth->tty == vtnr && auth->type == Display::Treeland) + return true; + } + return false; +} + /** * Callback function of disableRender * @@ -62,14 +76,11 @@ static void renderDisabled([[maybe_unused]] void *data, struct wl_callback *call } auto user = daemonApp->displayManager()->findUserByVt(activeVt); + bool isTreeland = isVtRunningTreeland(activeVt); auto conn = daemonApp->treelandConnector(); qDebug("Next VT: %d, user: %s", activeVt, user.isEmpty() ? "None" : qPrintable(user)); - if (user.isEmpty()) { - // Switch to a TTY, deactivate treeland session. - conn->switchToGreeter(); - conn->deactivateSession(); - } else { + if (isTreeland) { // If user is not empty, it means the switching can be issued by // ddm-helper. It uses VT signals from VirtualTerminal.h, // which is not what we want, so we should acquire VT control here. @@ -78,7 +89,11 @@ static void renderDisabled([[maybe_unused]] void *data, struct wl_callback *call close(activeVtFd); conn->enableRender(); - conn->switchToUser(user); + conn->switchToUser(user.isEmpty() ? "dde" : user); + } else { + // Switch to a TTY, deactivate treeland session. + conn->switchToGreeter(); + conn->deactivateSession(); } } @@ -96,7 +111,7 @@ static void onAcquireDisplay() { int vtnr = VirtualTerminal::getVtActive(fd); auto user = daemonApp->displayManager()->findUserByVt(vtnr); auto conn = daemonApp->treelandConnector(); - if (!user.isEmpty()) { + if (isVtRunningTreeland(vtnr)) { qDebug("Activate session at VT %d for user %s", vtnr, qPrintable(user)); conn->activateSession(); conn->enableRender(); diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp index 9d01caa..60a77e0 100644 --- a/src/daemon/XorgDisplayServer.cpp +++ b/src/daemon/XorgDisplayServer.cpp @@ -21,19 +21,11 @@ #include "XorgDisplayServer.h" #include "Configuration.h" -#include "DaemonApp.h" #include "Display.h" -#include "Seat.h" #include #include -#include #include -#include - -#include - -#include #include #include @@ -100,7 +92,7 @@ namespace DDM { process->setProgram(mainConfig.X11.ServerPath.get()); args << mainConfig.X11.ServerArguments.get().split(QLatin1Char(' '), Qt::SkipEmptyParts) << QStringLiteral("-background") << QStringLiteral("none") - << QStringLiteral("-seat") << static_cast(parent())->seat->name() + << QStringLiteral("-seat") << static_cast(parent())->name << QStringLiteral("vt%1").arg(vt) << QStringLiteral("-auth") << m_xauth.authPath() << QStringLiteral("-noreset") diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index c76fefb..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -set(QT_USE_QTTEST TRUE) - -include_directories(../src/common) - -set(ConfigurationTest_SRCS ConfigurationTest.cpp ../src/common/ConfigReader.cpp) -add_executable(ConfigurationTest ${ConfigurationTest_SRCS}) -add_test(NAME Configuration COMMAND ConfigurationTest) - -target_link_libraries(ConfigurationTest Qt${QT_MAJOR_VERSION}::Core Qt${QT_MAJOR_VERSION}::Test) - -set(QMLThemeConfigTest_SRCS QMLThemeConfigTest.cpp ../src/common/ThemeConfig.cpp ../src/common/ThemeConfig.h) -add_executable(QMLThemeConfigTest ${QMLThemeConfigTest_SRCS}) -target_include_directories(QMLThemeConfigTest PRIVATE ../src/common/) -add_test(NAME QMLThemeConfig COMMAND QMLThemeConfigTest -platform offscreen -input ${CMAKE_CURRENT_SOURCE_DIR}/QMLThemeConfigTest.qml WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(QMLThemeConfigTest PRIVATE Qt${QT_MAJOR_VERSION}::Quick Qt${QT_MAJOR_VERSION}::QuickTest) - -set(SessionTest_SRCS SessionTest.cpp ../src/common/Configuration.cpp ../src/common/ConfigReader.cpp ../src/common/Session.cpp) -add_executable(SessionTest ${SessionTest_SRCS}) -target_include_directories(SessionTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../src/common) -add_test(NAME Session COMMAND SessionTest) -target_link_libraries(SessionTest Qt${QT_MAJOR_VERSION}::Core Qt${QT_MAJOR_VERSION}::Test) diff --git a/test/ConfigurationTest.cpp b/test/ConfigurationTest.cpp deleted file mode 100644 index 17c9f74..0000000 --- a/test/ConfigurationTest.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Configuration parser tests - * Copyright (C) 2014 Martin Bříza - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include "ConfigurationTest.h" -#include - -#include -#include -#include - -QTEST_MAIN(ConfigurationTest); - -void ConfigurationTest::initTestCase() { } - -void ConfigurationTest::cleanupTestCase() { } - -void ConfigurationTest::init() { - QFile::remove(CONF_FILE); - QDir(CONF_DIR).removeRecursively(); - QDir().mkdir(CONF_DIR); - QDir(SYS_CONF_DIR).removeRecursively(); - QDir().mkdir(SYS_CONF_DIR); - QFile::remove(CONF_FILE_COPY); - config = new TestConfig; -} - -void ConfigurationTest::cleanup() { - QFile::remove(CONF_FILE); - QDir(CONF_DIR).removeRecursively(); - QDir(SYS_CONF_DIR).removeRecursively(); - QFile::remove(CONF_FILE_COPY); - if (config) - delete config; - config = nullptr; -} - -void ConfigurationTest::Basic() { - QVERIFY(config->String.get() == TEST_STRING_1); - QVERIFY(config->Int.get() == TEST_INT_1); - QVERIFY(config->StringList.get() == QStringList(TEST_STRINGLIST_1)); - QVERIFY(config->Boolean.get() == TEST_BOOL_1); - config->save(); - QVERIFY(!QFile::exists(CONF_FILE)); - config->String.set(config->String.get().append(QStringLiteral(" Appended"))); - config->save(); - QVERIFY(QFile::exists(CONF_FILE)); - config->String.set(config->String.get().append(QStringLiteral(" Appended Again"))); - config->save(); - QVERIFY(QFile::exists(CONF_FILE)); -} - -void ConfigurationTest::Sections() { - QVERIFY(config->Section.String.get() == TEST_STRING_1); - QVERIFY(config->Section.Int.get() == TEST_INT_1); - QVERIFY(config->Section.StringList.get() == QStringList(TEST_STRINGLIST_1)); - QVERIFY(config->Section.Boolean.get() == TEST_BOOL_1); - config->save(); - QVERIFY(!QFile::exists(CONF_FILE)); - config->Section.String.set(config->Section.String.get().append(QStringLiteral(" Appended"))); - config->save(); - QVERIFY(QFile::exists(CONF_FILE)); - config->Section.String.set(config->Section.String.get().append(QStringLiteral(" Appended Again"))); - config->save(); - QVERIFY(QFile::exists(CONF_FILE)); -} - -void ConfigurationTest::Unused() { - QFile confFile(CONF_FILE); - QFile confCopy(CONF_FILE_COPY); - confFile.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFile.write("InvalidGeneralValue=(null)\n"); - confFile.write("#InvalidSection Comment\n"); - confFile.write("[InvalidSection]\n"); - confFile.write("BadSectionValue=0\n"); - confFile.close(); - config->load(); - config->String.set(QStringLiteral("Changed String")); - config->Section.String.set(QStringLiteral("Changed String")); - config->save(); - QFile::copy(CONF_FILE, CONF_FILE_COPY); - config->load(); - config->save(); - QVERIFY(confFile.open(QIODevice::ReadOnly)); - QVERIFY(confCopy.open(QIODevice::ReadOnly)); - // the file must not change on consecutive loads and reads - QByteArray contents = confFile.readAll(); - QVERIFY(contents == confCopy.readAll()); - QVERIFY(contents.contains("InvalidGeneralValue")); - QVERIFY(contents.contains("InvalidSection")); - QVERIFY(contents.contains("BadSectionValue")); -} - -void ConfigurationTest::LineChanges() { - QFile confFile(CONF_FILE); - QFile confCopy(CONF_FILE_COPY); - // put some junk there to make it a bit harder to parse - confFile.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFile.write("InvalidGeneralValue=(null)\n"); - confFile.close(); - // assuming the integers will be of the same length when saved - config->Int.set(1); - config->save(); - QFile::copy(CONF_FILE, CONF_FILE_COPY); - config->Int.set(2); - config->save(); - QVERIFY(confFile.size() == confCopy.size()); -} - -void ConfigurationTest::CustomEnum() { - - QTest::qWait(2000); - QFile confFile(CONF_FILE); - confFile.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFile.write("Custom=bar\n"); - confFile.close(); - QVERIFY(config->Custom.get() == TestConfig::FOO); - config->load(); - QVERIFY(config->Custom.get() == TestConfig::BAR); - config->Custom.set(TestConfig::BAZ); - config->save(); - QVERIFY(confFile.open(QIODevice::ReadOnly)); - QByteArray contents = confFile.readAll(); - QVERIFY(contents.contains("baz")); - QVERIFY(!contents.contains("bar")); - QVERIFY(!contents.contains("foo")); -} - -void ConfigurationTest::RightOnInit() { - delete config; - QFile confFile(CONF_FILE); - confFile.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFile.write("String=a\n"); - confFile.write("Int=99999\n"); - confFile.write("StringList=a,b,c,qwertzuiop\n"); - confFile.write("Boolean=false\n"); - confFile.write("Custom=null\n"); - confFile.close(); - config = new TestConfig; - QVERIFY(config->String.get() == QStringLiteral("a")); - QVERIFY(config->Int.get() == 99999); - QVERIFY(config->StringList.get() == QStringList({QStringLiteral("a"), QStringLiteral("b"), QStringLiteral("c"), QStringLiteral("qwertzuiop")})); - QVERIFY(config->Boolean.get() == false); - QVERIFY(config->Custom.get() == TestConfig::BAZ); -} - - -void ConfigurationTest::RightOnInitDir() { - delete config; - - QFile confFileA(SYS_CONF_DIR+QStringLiteral("/0001A")); - confFileA.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFileA.write("Custom=Foo\n"); //overriden by B - confFileA.write("Boolean=false\n"); - confFileA.close(); - - QFile confFileB(CONF_DIR+QStringLiteral("/0001A")); - confFileB.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFileB.write("String=a\n"); //overriden by C - confFileB.write("Custom=Bar\n"); - confFileB.write("StringList=a,b,c\n"); - confFileB.write("Int=1111111\n"); //this is set in this config file but overriden in CONF_FILE - confFileB.close(); - - QFile confFileC(CONF_DIR+QStringLiteral("/0001B")); - confFileC.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFileC.write("String=b\n"); - confFileC.write("Int=1111111\n"); //overriden in CONF_FILE - confFileC.close(); - - QFile confFileMain(CONF_FILE); - confFileMain.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFileMain.write("Int=99999\n"); - confFileMain.close(); - confFileB.close(); - - config = new TestConfig; - QVERIFY(config->StringList.get() == QStringList({QStringLiteral("a"), QStringLiteral("b"), QStringLiteral("c")})); - QVERIFY(config->String.get() == QStringLiteral("b")); - QVERIFY(config->Int.get() == 99999); - QVERIFY(config->Custom.get() == TestConfig::BAR); - QVERIFY(config->Boolean.get() == false); -} - -void ConfigurationTest::FileChanged() -{ - QVERIFY(config->String.get() == QStringLiteral("Test Variable Initial String")); - - QTest::qWait(2000); - - //test from no file to a file - QFile confFile(CONF_FILE); - confFile.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFile.write("String=a\n"); - confFile.close(); - - config->load(); - QVERIFY(config->String.get() == QStringLiteral("a")); - - //test file changed - //wait 2 seconds so timestamp is definitely 1 second apart - QTest::qWait(2000); - - confFile.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFile.write("String=b\n"); - confFile.close(); - - config->load(); - QVERIFY(config->String.get() == QStringLiteral("b")); - - QTest::qWait(2000); - - //add file to conf dir - QFile confFileA(CONF_DIR+QStringLiteral("/0001A")); - confFileA.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFileA.write("Int=1111111\n"); //this is set in this config file but overriden in CONF_FILE - confFileA.close(); - config->load(); - QVERIFY(config->Int.get() ==1111111); - - QTest::qWait(2000); - //modify existing file in conf dir - - confFileA.open(QIODevice::WriteOnly | QIODevice::Truncate); - confFileA.write("Int=222222\n"); //this is set in this config file but overriden in CONF_FILE - confFileA.close(); - config->load(); - QVERIFY(config->Int.get() == 222222); -} - -#include "moc_ConfigurationTest.cpp" diff --git a/test/ConfigurationTest.h b/test/ConfigurationTest.h deleted file mode 100644 index 6061533..0000000 --- a/test/ConfigurationTest.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Configuration parser tests - * Copyright (C) 2014 Martin Bříza - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef CONFIGURATIONTEST_H -#define CONFIGURATIONTEST_H - -#include -#include - -#include "ConfigReader.h" - -#define CONF_FILE QStringLiteral("test.conf") -#define CONF_DIR QStringLiteral("testconfdir") -#define SYS_CONF_DIR QStringLiteral("testconfdir2") -#define CONF_FILE_COPY QStringLiteral("test_copy.conf") - -#define TEST_STRING_1_PLAIN "Test Variable Initial String" -#define TEST_STRING_1 QStringLiteral(TEST_STRING_1_PLAIN) -#define TEST_INT_1 12345 -#define TEST_STRINGLIST_1 {QStringLiteral("String1"), QStringLiteral("String2")} -#define TEST_BOOL_1 true - -Config (TestConfig, CONF_FILE, CONF_DIR, SYS_CONF_DIR, - enum CustomType { - FOO, - BAR, - BAZ - }; - Entry( String, QString, _S(TEST_STRING_1_PLAIN), _S("Test String Description")); - Entry( Int, int, TEST_INT_1, _S("Test Integer Description")); - Entry(StringList, QStringList, QStringList(TEST_STRINGLIST_1), _S("Test StringList Description")); - Entry( Boolean, bool, TEST_BOOL_1, _S("Test Boolean Description")); - Entry( Custom, CustomType, FOO, _S("Custom type imitating NumState")); - Section(Section, - Entry( String, QString, _S(TEST_STRING_1_PLAIN), _S("Test String Description")); - Entry( Int, int, TEST_INT_1, _S("Test Integer Description")); - Entry(StringList, QStringList, QStringList(TEST_STRINGLIST_1), _S("Test StringList Description")); - Entry( Boolean, bool, TEST_BOOL_1, _S("Test Boolean Description")); - ); -); - -inline QTextStream& operator>>(QTextStream &str, TestConfig::CustomType &state) { - QString text = str.readLine().trimmed(); - if (text.compare(QLatin1String("foo"), Qt::CaseInsensitive) == 0) - state = TestConfig::FOO; - else if (text.compare(QLatin1String("bar"), Qt::CaseInsensitive) == 0) - state = TestConfig::BAR; - else - state = TestConfig::BAZ; - return str; -} - -inline QTextStream& operator<<(QTextStream &str, const TestConfig::CustomType &state) { - if (state == TestConfig::FOO) - str << "foo"; - else if (state == TestConfig::BAR) - str << "bar"; - else - str << "baz"; - return str; -} - -class ConfigurationTest : public QObject -{ - Q_OBJECT -private slots: - void initTestCase(); - void cleanupTestCase(); - - void init(); - void cleanup(); - - void Basic(); - void Sections(); - void Unused(); - void LineChanges(); - void CustomEnum(); - void RightOnInit(); - void RightOnInitDir(); - void FileChanged(); - -private: - TestConfig *config; -}; - -#endif // CONFIGURATIONTEST_H diff --git a/test/QMLThemeConfigTest.cpp b/test/QMLThemeConfigTest.cpp deleted file mode 100644 index b5c3e69..0000000 --- a/test/QMLThemeConfigTest.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2023 Fabian Vogt -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -#include -#include -#include - -#include "ThemeConfig.h" - -class Setup : public QObject -{ - Q_OBJECT -public slots: - void qmlEngineAvailable(QQmlEngine *engine) - { - auto *config = new DDM::ThemeConfig(QStringLiteral("theme.conf"), this); - engine->rootContext()->setContextProperty(QStringLiteral("config"), config); - } -}; - -QUICK_TEST_MAIN_WITH_SETUP(QMLThemeConfigTest, Setup) - -#include "QMLThemeConfigTest.moc" diff --git a/test/QMLThemeConfigTest.qml b/test/QMLThemeConfigTest.qml deleted file mode 100644 index a658fad..0000000 --- a/test/QMLThemeConfigTest.qml +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2023 Fabian Vogt -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -import QtQuick 2.3 -import QtTest 1.0 - -TestCase { - name: "QMLThemeConfigTest" - - function test_keys() { - let keys = Object.keys(config); - compare(keys.indexOf("doesnotexist"), -1); - verify(keys.indexOf("someInteger") >= 0); - keys = config.keys(); - compare(keys.indexOf("doesnotexist"), -1); - verify(keys.indexOf("someInteger") >= 0); - } - - // Everything is a string - function test_propertyAPI() { - compare(config.doesnotexist, undefined); - compare(config.someTrueBool, "yes"); - compare(!!config.someTrueBool, true); - compare(config.someFalseBool, "false"); - // "false" as a string is truthy! - compare(!!config.someFalseBool, true); - compare(config.someInteger, "042"); - compare(+config.someInteger, 42); - compare(config.someRealNumber, "01.5"); - compare(+config.someRealNumber, 1.5); - compare(config.someString, "Pie/180"); - } - - // Strings are converted to specific types - function test_typedAPI() { - compare(config.stringValue("doesnotexist"), ""); - compare(config.boolValue("someTrueBool"), true); - compare(config.boolValue("someFalseBool"), false); - // "false" as a string is truthy! - compare(!!config.someFalseBool, true); - compare(config.stringValue("someInteger"), "042"); - compare(config.intValue("someInteger"), 42); - compare(config.realValue("someRealNumber"), 1.5); - // conversion fails -> 0 - compare(config.intValue("someRealNumber"), 0); - compare(config.stringValue("someString"), "Pie/180"); - // conversion fails -> 0 - compare(config.intValue("someString"), 0); - compare(config.realValue("someString"), 0); - } -} diff --git a/test/SessionTest.cpp b/test/SessionTest.cpp deleted file mode 100644 index 8876cab..0000000 --- a/test/SessionTest.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** -* Copyright (c) 2023 Fabian Vogt -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the -* Free Software Foundation, Inc., -* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -***************************************************************************/ - -#include "Session.h" - -#include -#include - -class SessionTest : public QObject { - Q_OBJECT -private slots: - void testCLocale() - { - QLocale::setDefault(QLocale::c()); - auto fileName = QFINDTESTDATA("plasmawayland-dev.desktop"); - DDM::Session session(DDM::Session::WaylandSession, fileName); - QVERIFY(session.isValid()); - QCOMPARE(session.xdgSessionType(), QStringLiteral("wayland")); - QCOMPARE(session.fileName(), fileName); - QCOMPARE(session.displayName(), QStringLiteral("Plasma (Development, Wayland /usr/bin)")); - QCOMPARE(session.comment(), QStringLiteral("Plasma by KDE")); - QCOMPARE(session.exec(), QStringLiteral("/usr/lib64/libexec/plasma-dbus-run-session-if-needed /usr/lib64/libexec/startplasma-dev.sh -wayland")); - QCOMPARE(session.tryExec(), QString()); - QCOMPARE(session.desktopSession(), QStringLiteral("plasmawayland-dev")); - QCOMPARE(session.desktopNames(), QStringLiteral("KDE")); - QCOMPARE(session.isHidden(), false); - QCOMPARE(session.isNoDisplay(), false); - } - void testKOLocale() - { - QLocale::setDefault(QLocale{QStringLiteral("ko_KO")}); - auto fileName = QFINDTESTDATA("plasmawayland-dev.desktop"); - DDM::Session session(DDM::Session::WaylandSession, fileName); - QVERIFY(session.isValid()); - QCOMPARE(session.xdgSessionType(), QStringLiteral("wayland")); - QCOMPARE(session.fileName(), fileName); - QCOMPARE(session.displayName(), QStringLiteral("Plasma(\uAC1C\uBC1C, Wayland /usr/bin)")); - QCOMPARE(session.comment(), QStringLiteral("KDE Plasma")); - QCOMPARE(session.exec(), QStringLiteral("/usr/lib64/libexec/plasma-dbus-run-session-if-needed /usr/lib64/libexec/startplasma-dev.sh -wayland")); - QCOMPARE(session.tryExec(), QString()); - QCOMPARE(session.desktopSession(), QStringLiteral("plasmawayland-dev")); - QCOMPARE(session.desktopNames(), QStringLiteral("KDE")); - QCOMPARE(session.isHidden(), false); - QCOMPARE(session.isNoDisplay(), false); - } -}; - -QTEST_MAIN(SessionTest); - -#include "SessionTest.moc" diff --git a/test/plasmawayland-dev.desktop b/test/plasmawayland-dev.desktop deleted file mode 100644 index 0fa1b87..0000000 --- a/test/plasmawayland-dev.desktop +++ /dev/null @@ -1,106 +0,0 @@ -[Desktop Entry] -Exec=/usr/lib64/libexec/plasma-dbus-run-session-if-needed /usr/lib64/libexec/startplasma-dev.sh -wayland -DesktopNames=KDE -Name=Plasma (Development, Wayland /usr/bin) -Name[ar]=بلازما (تطوير, ويلاند /usr/bin) -Name[az]=Plasma (Tərtib mərhələsində olan Wayland /usr/bin) -Name[be]=Plasma (Development, Wayland /usr/bin) -Name[bg]=Plasma (Development, Wayland /usr/bin) -Name[ca]=Plasma (Desenvolupament, Wayland /usr/bin) -Name[ca@valencia]=Plasma (Desenvolupament, Wayland /usr/bin) -Name[da]=Plasma (udvikling, Wayland /usr/bin) -Name[de]=Plasma (Development, Wayland /usr/bin) -Name[en_GB]=Plasma (Development, Wayland /usr/bin) -Name[es]=Plasma (Desarrollo, Wayland /usr/bin) -Name[et]=Plasma (arendus, Wayland /usr/bin) -Name[eu]=Plasma (Garapena, Wayland /usr/bin) -Name[fi]=Plasma (kehitys, Wayland /usr/bin) -Name[fr]=Plasma (Développement, Wayland /usr/bin) -Name[gl]=Plasma (desenvolvemento, Wayland /usr/bin) -Name[hi]=प्लाज़्मा (विकास, वैलेंड /usr/bin) -Name[hu]=Plasma (Fejlesztői verzió, Wayland /usr/bin) -Name[ia]=Plasma (Disveloppamento, Wayland /usr/bin) -Name[id]=Plasma (Development, Wayland /usr/bin) -Name[is]=Plasma (Þróunarútgáfa, Wayland /usr/bin) -Name[it]=Plasma (Sviluppo, Wayland /usr/bin) -Name[ja]=Plasma (Development, Wayland /usr/bin) -Name[ka]=Plasma (Development, Wayland /usr/bin) -Name[ko]=Plasma(개발, Wayland /usr/bin) -Name[lt]=Plasma (Plėtojimas, Wayland /usr/bin) -Name[ml]=പ്ലാസ്മ (വികസനം, വേലാൻഡ് /usr/bin) -Name[nl]=Plasma (Ontwikkeling, Wayland /usr/bin) -Name[nn]=Plasma (utvikling, Wayland /usr/bin) -Name[pa]=ਪਲਾਜ਼ਮਾ (ਡਿਵੈਲਪਮੈਂਟ, ਵੇਅਲੈਂਡ /usr/bin) -Name[pl]=Plazma (Rozwój , Wayland /usr/bin) -Name[pt]=Plasma (Desenvolvimento, Wayland /usr/bin) -Name[pt_BR]=Plasma (Desenvolvimento, Wayland /usr/bin) -Name[ro]=Plasma (Dezvoltare, Wayland /usr/bin) -Name[ru]=Plasma (разрабатываемая версия, Wayland /usr/bin) -Name[sk]=Plasma (Development, Wayland /usr/bin) -Name[sl]=Plasma (Razvoj, Wayland /usr/bin) -Name[sv]=Plasma (utveckling, Wayland /usr/bin) -Name[ta]=பிளாஸ்மா (Development, Wayland /usr/bin) -Name[tr]=Plasma (Geliştirme, Wayland $ {CMAKE_INSTALL_FULL_BINDIR}) -Name[uk]=Плазма (Розробка, Wayland /usr/bin) -Name[vi]=Plasma (Phát triển, Wayland /usr/bin) -Name[x-test]=xxPlasma (Development, Wayland /usr/bin)xx -Name[zh_CN]=Plasma (Development, Wayland /usr/bin) -Name[zh_TW]=Plasma (開發版本,Wayland /usr/bin) -Comment=Plasma by KDE -Comment[ar]=بلازما كدي -Comment[az]=KDE Plasma -Comment[be]=Plasma KDE -Comment[bg]=Plasma от KDE -Comment[bs]=Plazma od strane KDe -Comment[ca]=Plasma, creat per la comunitat KDE -Comment[ca@valencia]=Plasma, creat per la comunitat KDE -Comment[cs]=Plasma z KDE -Comment[da]=Plasma fra KDE -Comment[de]=Plasma von KDE -Comment[el]=Plasma από το KDE -Comment[en_GB]=Plasma by KDE -Comment[es]=Plasma, por KDE -Comment[et]=KDE Plasma -Comment[eu]=KDEren Plasma -Comment[fi]=Plasma KDE:ltä -Comment[fr]=Plasma, par KDE -Comment[gl]=Plasma, fornecido por KDE. -Comment[he]=פלזמה באמצעות KDE -Comment[hi]=केडीइ द्वारा प्लाज़्मा -Comment[hsb]=Plasma wot KDE -Comment[hu]=Plasma a KDE-től -Comment[ia]=Plasma per KDE -Comment[id]=Plasma oleh KDE -Comment[is]=Plasma frá KDE -Comment[it]=Plasma di KDE -Comment[ja]=Plasma by KDE -Comment[ka]=Plasma, KDE-სგან -Comment[ko]=KDE Plasma -Comment[lt]=Plasma pagal KDE -Comment[ml]=കെഡിഇയുടെ പ്ലാസ്മ -Comment[nb]=Plasma av KDE -Comment[nds]=Plasma vun KDE -Comment[nl]=Plasma door KDE -Comment[nn]=Plasma frå KDE -Comment[pa]=KDE ਵਲੋਂ ਪਲਾਜ਼ਮਾ -Comment[pl]=Plazma dzięki KDE -Comment[pt]=Plasma do KDE -Comment[pt_BR]=Plasma do KDE -Comment[ro]=Plasma, de către KDE -Comment[ru]=KDE Plasma -Comment[sk]=Plasma od KDE -Comment[sl]=KDE Plasma -Comment[sr]=Плазма од КДЕ‑а -Comment[sr@ijekavian]=Плазма од КДЕ‑а -Comment[sr@ijekavianlatin]=Plasma od KDE‑a -Comment[sr@latin]=Plasma od KDE‑a -Comment[sv]=Plasma av KDE -Comment[ta]=கே.டீ.யீ. வழங்கும் பிளாஸ்மா -Comment[tg]=Plasma аз ҷониби KDE -Comment[tr]=KDE Plasma -Comment[uk]=Плазма KDE -Comment[vi]=Plasma, do KDE -Comment[x-test]=xxPlasma by KDExx -Comment[zh_CN]=KDE Plasma -Comment[zh_TW]=Plasma by KDE -X-KDE-PluginInfo-Version=5.27.0 diff --git a/test/theme.conf b/test/theme.conf deleted file mode 100644 index cb74cf0..0000000 --- a/test/theme.conf +++ /dev/null @@ -1,6 +0,0 @@ -[General] -someTrueBool=yes -someFalseBool=false -someInteger=042 -someRealNumber=01.5 -someString="Pie/180"