Add warnings for missing Wayland libs and features (#7492)
* Add warnings for libei and libportal * Add warning about experimental Wayland support * Update ChangeLog * Move GUI res files to root res dir * Fixed crazy qrc shenanigans * Move Wayland warning logic, add tests, improve core retry * Also install py modules with pip since meson can be in venv * Throw error when no libei * Add warnings when no libportal * Allow failure then success to show related to Wayland (for switching modes) * Fixed formatting * Fixed includes * Simplify warning message * Add log hint * Show warning when error already shown * Only check for Wayland if X or libei * Add error message when quitting dur to remote desktop error * Improve consistency of portal log lines
|
|
@ -19,6 +19,7 @@ Enhancements:
|
||||||
- #7485 Use `.venv` dir for as Python venv and cache
|
- #7485 Use `.venv` dir for as Python venv and cache
|
||||||
- #7488 Only wait for elevated process to end when arg is set
|
- #7488 Only wait for elevated process to end when arg is set
|
||||||
- #7489 Add `--config-toml` arg for TOML config file
|
- #7489 Add `--config-toml` arg for TOML config file
|
||||||
|
- #7492 Add warnings for `libei` and `libportal`
|
||||||
|
|
||||||
# 1.15.1
|
# 1.15.1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,8 @@ config:
|
||||||
sudo apt-get install -y \
|
sudo apt-get install -y \
|
||||||
python3-attr \
|
python3-attr \
|
||||||
python3-jinja2 \
|
python3-jinja2 \
|
||||||
libsystemd-dev
|
libsystemd-dev &&
|
||||||
|
pip install attrs jinja2
|
||||||
|
|
||||||
ubuntu: *debian_libei
|
ubuntu: *debian_libei
|
||||||
linuxmint: *debian_libei
|
linuxmint: *debian_libei
|
||||||
|
|
@ -170,7 +171,8 @@ config:
|
||||||
sudo dnf install -y \
|
sudo dnf install -y \
|
||||||
python3-attrs \
|
python3-attrs \
|
||||||
python3-jinja2 \
|
python3-jinja2 \
|
||||||
systemd-devel
|
systemd-devel &&
|
||||||
|
pip install attrs jinja2
|
||||||
|
|
||||||
rhel: *fedora_libei
|
rhel: *fedora_libei
|
||||||
rocky: *fedora_libei
|
rocky: *fedora_libei
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"hotspots",
|
"hotspots",
|
||||||
"Hutterer",
|
"Hutterer",
|
||||||
"ifdef",
|
"ifdef",
|
||||||
|
"INPUTCAPTURE",
|
||||||
"integtests",
|
"integtests",
|
||||||
"keychain",
|
"keychain",
|
||||||
"Keychains",
|
"Keychains",
|
||||||
|
|
@ -69,7 +70,8 @@
|
||||||
"vmactions",
|
"vmactions",
|
||||||
"Volker",
|
"Volker",
|
||||||
"whot",
|
"whot",
|
||||||
"winget"
|
"winget",
|
||||||
|
"XWINDOWS"
|
||||||
],
|
],
|
||||||
"ignoreWords": [],
|
"ignoreWords": [],
|
||||||
"import": []
|
"import": []
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/res">
|
<qresource>
|
||||||
<file>icons/16x16/synergy.png</file>
|
<file>icons/16x16/synergy.png</file>
|
||||||
<file>icons/64x64/video-display.png</file>
|
<file>icons/64x64/video-display.png</file>
|
||||||
<file>icons/64x64/user-trash.png</file>
|
<file>icons/64x64/user-trash.png</file>
|
||||||
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 450 B |
|
Before Width: | Height: | Size: 905 B After Width: | Height: | Size: 905 B |
|
Before Width: | Height: | Size: 693 B After Width: | Height: | Size: 693 B |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 919 B After Width: | Height: | Size: 919 B |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
|
@ -20,26 +20,23 @@ set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
set(res_dir ${CMAKE_SOURCE_DIR}/res/gui)
|
||||||
|
set(qrc_file ${res_dir}/Synergy.qrc)
|
||||||
|
|
||||||
file(
|
file(
|
||||||
GLOB
|
GLOB
|
||||||
GUI_SOURCE_FILES
|
sources
|
||||||
src/*.cpp
|
src/*.cpp
|
||||||
src/*.h
|
src/*.h
|
||||||
src/validators/*
|
src/validators/*
|
||||||
src/widgets/*)
|
src/widgets/*)
|
||||||
file(GLOB GUI_UI_FILES src/*.ui)
|
file(GLOB ui_files src/*.ui)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(GUI_RC_FILES res/win/Synergy.rc ${CMAKE_BINARY_DIR}/src/version.rc)
|
set(rc_files ${res_dir}/win/Synergy.rc ${CMAKE_BINARY_DIR}/src/version.rc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(
|
add_executable(${target} WIN32 ${sources} ${ui_files} ${rc_files} ${qrc_file})
|
||||||
${target} WIN32
|
|
||||||
${GUI_SOURCE_FILES}
|
|
||||||
${GUI_UI_FILES}
|
|
||||||
${GUI_RC_FILES}
|
|
||||||
res/Synergy.qrc
|
|
||||||
${QM_FILES})
|
|
||||||
|
|
||||||
# regular exe headers
|
# regular exe headers
|
||||||
include_directories(./src)
|
include_directories(./src)
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ int AboutDialog::exec() {
|
||||||
void AboutDialog::updateLogo() const {
|
void AboutDialog::updateLogo() const {
|
||||||
if (isDarkMode()) {
|
if (isDarkMode()) {
|
||||||
qDebug("dark mode detected, showing dark logo");
|
qDebug("dark mode detected, showing dark logo");
|
||||||
QPixmap logo(":/res/image/about-dark.png");
|
QPixmap logo(":/image/about-dark.png");
|
||||||
if (!logo.isNull()) {
|
if (!logo.isNull()) {
|
||||||
m_pLabel_Logo->setPixmap(logo);
|
m_pLabel_Logo->setPixmap(logo);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap">
|
<property name="pixmap">
|
||||||
<pixmap resource="../res/Synergy.qrc">:/res/image/about-light.png</pixmap>
|
<pixmap>:/image/about-light.png</pixmap>
|
||||||
</property>
|
</property>
|
||||||
<property name="scaledContents">
|
<property name="scaledContents">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|
@ -249,9 +249,6 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
|
||||||
<include location="../res/Synergy.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>buttonOk</sender>
|
<sender>buttonOk</sender>
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,14 @@
|
||||||
#include "gui/styles.h"
|
#include "gui/styles.h"
|
||||||
#include "gui/tls/TlsFingerprint.h"
|
#include "gui/tls/TlsFingerprint.h"
|
||||||
#include "license/License.h"
|
#include "license/License.h"
|
||||||
|
#include "platform/wayland.h"
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
#include "gui/OSXHelpers.h"
|
#include "gui/OSXHelpers.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
|
@ -69,11 +73,11 @@ using CoreMode = CoreProcess::Mode;
|
||||||
using CoreConnectionState = CoreProcess::ConnectionState;
|
using CoreConnectionState = CoreProcess::ConnectionState;
|
||||||
using CoreProcessState = CoreProcess::ProcessState;
|
using CoreProcessState = CoreProcess::ProcessState;
|
||||||
|
|
||||||
const auto kIconFile16 = ":/res/icons/16x16/synergy.png";
|
const auto kIconFile16 = ":/icons/16x16/synergy.png";
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
const auto kLightIconFile = ":/res/icons/64x64/synergy-light.png";
|
const auto kLightIconFile = ":/icons/64x64/synergy-light.png";
|
||||||
const auto kDarkIconFile = ":/res/icons/64x64/synergy-dark.png";
|
const auto kDarkIconFile = ":/icons/64x64/synergy-dark.png";
|
||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
|
|
||||||
MainWindow::MainWindow(ConfigScopes &configScopes, AppConfig &appConfig)
|
MainWindow::MainWindow(ConfigScopes &configScopes, AppConfig &appConfig)
|
||||||
|
|
@ -584,6 +588,12 @@ void MainWindow::onCoreProcessStarting() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WINAPI_XWINDOWS) or defined(WINAPI_LIBEI)
|
||||||
|
if (synergy::platform::isWayland()) {
|
||||||
|
m_WaylandWarnings.showOnce(this, m_CoreProcess.mode());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -844,6 +854,10 @@ void MainWindow::updateStatus() {
|
||||||
setStatus("Synergy is starting...");
|
setStatus("Synergy is starting...");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RetryPending:
|
||||||
|
setStatus("Synergy will retry in a moment...");
|
||||||
|
break;
|
||||||
|
|
||||||
case Stopping:
|
case Stopping:
|
||||||
setStatus("Synergy is stopping...");
|
setStatus("Synergy is stopping...");
|
||||||
break;
|
break;
|
||||||
|
|
@ -896,7 +910,8 @@ void MainWindow::onCoreProcessStateChanged(CoreProcessState state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == CoreProcessState::Started ||
|
if (state == CoreProcessState::Started ||
|
||||||
state == CoreProcessState::Starting) {
|
state == CoreProcessState::Starting ||
|
||||||
|
state == CoreProcessState::RetryPending) {
|
||||||
disconnect(
|
disconnect(
|
||||||
m_pButtonToggleStart, &QPushButton::clicked, m_pActionStartCore,
|
m_pButtonToggleStart, &QPushButton::clicked, m_pActionStartCore,
|
||||||
&QAction::trigger);
|
&QAction::trigger);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include "gui/core/ClientConnection.h"
|
#include "gui/core/ClientConnection.h"
|
||||||
#include "gui/core/CoreProcess.h"
|
#include "gui/core/CoreProcess.h"
|
||||||
#include "gui/core/ServerConnection.h"
|
#include "gui/core/ServerConnection.h"
|
||||||
|
#include "gui/core/WaylandWarnings.h"
|
||||||
#include "gui/tls/TlsUtility.h"
|
#include "gui/tls/TlsUtility.h"
|
||||||
#include "ui_MainWindowBase.h"
|
#include "ui_MainWindowBase.h"
|
||||||
|
|
||||||
|
|
@ -198,6 +199,7 @@ private:
|
||||||
bool m_Quitting = false;
|
bool m_Quitting = false;
|
||||||
synergy::gui::config::ServerConfigDialogState m_ServerConfigDialogState;
|
synergy::gui::config::ServerConfigDialogState m_ServerConfigDialogState;
|
||||||
bool m_SaveOnExit = true;
|
bool m_SaveOnExit = true;
|
||||||
|
synergy::gui::core::WaylandWarnings m_WaylandWarnings;
|
||||||
|
|
||||||
synergy::gui::ConfigScopes &m_ConfigScopes;
|
synergy::gui::ConfigScopes &m_ConfigScopes;
|
||||||
AppConfig &m_AppConfig;
|
AppConfig &m_AppConfig;
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap">
|
<property name="pixmap">
|
||||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/16x16/padlock.png</pixmap>
|
<pixmap>:/icons/16x16/padlock.png</pixmap>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -740,9 +740,6 @@
|
||||||
<tabstop>m_pButtonApply</tabstop>
|
<tabstop>m_pButtonApply</tabstop>
|
||||||
<tabstop>m_pButtonToggleStart</tabstop>
|
<tabstop>m_pButtonToggleStart</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
|
||||||
<include location="../res/Synergy.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>m_pButtonToggleStart</sender>
|
<sender>m_pButtonToggleStart</sender>
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap">
|
<property name="pixmap">
|
||||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/64x64/user-trash.png</pixmap>
|
<pixmap>:/icons/64x64/user-trash.png</pixmap>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -1072,8 +1072,8 @@ Enabling this setting will disable the server config GUI.</string>
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../res/Synergy.qrc">
|
<iconset>
|
||||||
<normaloff>:/res/icons/64x64/folder.png</normaloff>:/res/icons/64x64/folder.png</iconset>
|
<normaloff>:/icons/64x64/folder.png</normaloff>:/icons/64x64/folder.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
|
|
@ -1179,9 +1179,6 @@ Enabling this setting will disable the server config GUI.</string>
|
||||||
<tabstop>m_pEditConfigFile</tabstop>
|
<tabstop>m_pEditConfigFile</tabstop>
|
||||||
<tabstop>m_pTabWidget</tabstop>
|
<tabstop>m_pTabWidget</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
|
||||||
<include location="../res/Synergy.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>m_pButtonBox</sender>
|
<sender>m_pButtonBox</sender>
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap">
|
<property name="pixmap">
|
||||||
<pixmap resource="../res/Synergy.qrc">:/res/image/welcome.png</pixmap>
|
<pixmap>:/image/welcome.png</pixmap>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="margin">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
|
|
@ -186,8 +186,5 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
|
||||||
<include location="../res/Synergy.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@
|
||||||
|
|
||||||
set(target gui)
|
set(target gui)
|
||||||
|
|
||||||
|
set(res_dir ${CMAKE_SOURCE_DIR}/res/gui)
|
||||||
|
set(qrc_file ${res_dir}/Synergy.qrc)
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
@ -33,7 +36,8 @@ if(ADD_HEADERS_TO_SOURCES)
|
||||||
list(APPEND sources ${headers})
|
list(APPEND sources ${headers})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(${target} STATIC ${sources} ${ui_files})
|
add_library(${target} STATIC ${sources} ${ui_files} ${qrc_file})
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${target}
|
${target}
|
||||||
license
|
license
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,8 @@ QString processStateToString(CoreProcess::ProcessState state) {
|
||||||
return "stopping";
|
return "stopping";
|
||||||
case Stopped:
|
case Stopped:
|
||||||
return "stopped";
|
return "stopped";
|
||||||
|
case RetryPending:
|
||||||
|
return "retry pending";
|
||||||
default:
|
default:
|
||||||
qFatal("invalid process state");
|
qFatal("invalid process state");
|
||||||
abort();
|
abort();
|
||||||
|
|
@ -184,6 +186,14 @@ CoreProcess::CoreProcess(
|
||||||
connect(
|
connect(
|
||||||
&m_pDeps->process(), &QProcessProxy::readyReadStandardError, this,
|
&m_pDeps->process(), &QProcessProxy::readyReadStandardError, this,
|
||||||
&CoreProcess::onProcessReadyReadStandardError);
|
&CoreProcess::onProcessReadyReadStandardError);
|
||||||
|
|
||||||
|
connect(&m_retryTimer, &QTimer::timeout, [this] {
|
||||||
|
if (m_processState == ProcessState::RetryPending) {
|
||||||
|
start();
|
||||||
|
} else {
|
||||||
|
qDebug("retry cancelled, process state is not retry pending");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreProcess::onIpcClientServiceReady() {
|
void CoreProcess::onIpcClientServiceReady() {
|
||||||
|
|
@ -227,7 +237,6 @@ void CoreProcess::onProcessReadyReadStandardError() {
|
||||||
void CoreProcess::onProcessFinished(int exitCode, QProcess::ExitStatus) {
|
void CoreProcess::onProcessFinished(int exitCode, QProcess::ExitStatus) {
|
||||||
const auto wasStarted = m_processState == ProcessState::Started;
|
const auto wasStarted = m_processState == ProcessState::Started;
|
||||||
|
|
||||||
setProcessState(ProcessState::Stopped);
|
|
||||||
setConnectionState(ConnectionState::Disconnected);
|
setConnectionState(ConnectionState::Disconnected);
|
||||||
|
|
||||||
if (exitCode == 0) {
|
if (exitCode == 0) {
|
||||||
|
|
@ -238,7 +247,16 @@ void CoreProcess::onProcessFinished(int exitCode, QProcess::ExitStatus) {
|
||||||
|
|
||||||
if (wasStarted) {
|
if (wasStarted) {
|
||||||
qDebug("desktop process was running, retrying in %d ms", kRetryDelay);
|
qDebug("desktop process was running, retrying in %d ms", kRetryDelay);
|
||||||
QTimer::singleShot(kRetryDelay, [this] { start(); });
|
|
||||||
|
if (m_retryTimer.isActive()) {
|
||||||
|
m_retryTimer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
setProcessState(ProcessState::RetryPending);
|
||||||
|
m_retryTimer.setSingleShot(true);
|
||||||
|
m_retryTimer.start(kRetryDelay);
|
||||||
|
} else {
|
||||||
|
setProcessState(ProcessState::Stopped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QTimer>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace synergy::gui {
|
namespace synergy::gui {
|
||||||
|
|
@ -55,7 +56,13 @@ public:
|
||||||
|
|
||||||
enum class Mode { None, Client, Server };
|
enum class Mode { None, Client, Server };
|
||||||
enum class Error { AddressMissing, StartFailed };
|
enum class Error { AddressMissing, StartFailed };
|
||||||
enum class ProcessState { Starting, Started, Stopping, Stopped };
|
enum class ProcessState {
|
||||||
|
Starting,
|
||||||
|
Started,
|
||||||
|
Stopping,
|
||||||
|
Stopped,
|
||||||
|
RetryPending
|
||||||
|
};
|
||||||
enum class ConnectionState { Disconnected, Connecting, Connected, Listening };
|
enum class ConnectionState { Disconnected, Connecting, Connected, Listening };
|
||||||
|
|
||||||
explicit CoreProcess(
|
explicit CoreProcess(
|
||||||
|
|
@ -130,6 +137,7 @@ private:
|
||||||
QMutex m_processMutex;
|
QMutex m_processMutex;
|
||||||
QString m_secureSocketVersion = "";
|
QString m_secureSocketVersion = "";
|
||||||
std::optional<ProcessMode> m_lastProcessMode = std::nullopt;
|
std::optional<ProcessMode> m_lastProcessMode = std::nullopt;
|
||||||
|
QTimer m_retryTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace synergy::gui
|
} // namespace synergy::gui
|
||||||
|
|
|
||||||
65
src/lib/gui/core/WaylandWarnings.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2024 Symless Ltd.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WaylandWarnings.h"
|
||||||
|
|
||||||
|
#include "messages.h"
|
||||||
|
|
||||||
|
using namespace synergy::platform;
|
||||||
|
|
||||||
|
namespace synergy::gui::core {
|
||||||
|
|
||||||
|
//
|
||||||
|
// WaylandWarnings::Deps
|
||||||
|
//
|
||||||
|
|
||||||
|
void WaylandWarnings::Deps::showWaylandLibraryError(QWidget *parent) {
|
||||||
|
messages::showWaylandLibraryError(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaylandWarnings::Deps::showWaylandExperimental(QWidget *parent) {
|
||||||
|
messages::showWaylandExperimental(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WaylandWarnings
|
||||||
|
//
|
||||||
|
|
||||||
|
void WaylandWarnings::showOnce(
|
||||||
|
QWidget *parent, CoreProcess::Mode mode, bool hasEi, bool hasPortal,
|
||||||
|
bool hasPortalInputCapture) {
|
||||||
|
|
||||||
|
const auto portalIcProblem =
|
||||||
|
!hasPortalInputCapture && mode == CoreProcess::Mode::Server;
|
||||||
|
|
||||||
|
if (!hasEi || !hasPortal || portalIcProblem) {
|
||||||
|
if (!m_errorShown) {
|
||||||
|
m_errorShown = true;
|
||||||
|
m_pDeps->showWaylandLibraryError(parent);
|
||||||
|
} else {
|
||||||
|
qWarning("missing required wayland lib(s) or feature");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_warningShown) {
|
||||||
|
m_warningShown = true;
|
||||||
|
m_pDeps->showWaylandExperimental(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace synergy::gui::core
|
||||||
49
src/lib/gui/core/WaylandWarnings.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2024 Symless Ltd.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "CoreProcess.h"
|
||||||
|
#include "platform/wayland.h"
|
||||||
|
|
||||||
|
namespace synergy::gui::core {
|
||||||
|
|
||||||
|
class WaylandWarnings {
|
||||||
|
public:
|
||||||
|
struct Deps {
|
||||||
|
virtual ~Deps() = default;
|
||||||
|
virtual void showWaylandExperimental(QWidget *parent);
|
||||||
|
virtual void showWaylandLibraryError(QWidget *parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit WaylandWarnings(
|
||||||
|
std::shared_ptr<Deps> deps = std::make_shared<Deps>())
|
||||||
|
: m_pDeps(deps) {}
|
||||||
|
|
||||||
|
void showOnce(
|
||||||
|
QWidget *parent, CoreProcess::Mode mode, bool hasEi = platform::kHasEi,
|
||||||
|
bool hasPortal = platform::kHasPortal,
|
||||||
|
bool hasPortalInputCapture = platform::kHasPortalInputCapture);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_errorShown{false};
|
||||||
|
bool m_warningShown{false};
|
||||||
|
std::shared_ptr<Deps> m_pDeps;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace synergy::gui::core
|
||||||
|
|
@ -277,8 +277,8 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../res/Synergy.qrc">
|
<iconset>
|
||||||
<normaloff>:/res/icons/64x64/folder.png</normaloff>:/res/icons/64x64/folder.png</iconset>
|
<normaloff>:/icons/64x64/folder.png</normaloff>:/icons/64x64/folder.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
|
|
@ -567,8 +567,8 @@
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../res/Synergy.qrc">
|
<iconset>
|
||||||
<normaloff>:/res/icons/64x64/folder.png</normaloff>:/res/icons/64x64/folder.png</iconset>
|
<normaloff>:/icons/64x64/folder.png</normaloff>:/icons/64x64/folder.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
|
|
@ -753,9 +753,6 @@
|
||||||
<tabstop>m_pRadioSystemScope</tabstop>
|
<tabstop>m_pRadioSystemScope</tabstop>
|
||||||
<tabstop>m_pComboElevate</tabstop>
|
<tabstop>m_pComboElevate</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
|
||||||
<include location="../res/Synergy.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>m_pButtonBox</sender>
|
<sender>m_pButtonBox</sender>
|
||||||
|
|
|
||||||
|
|
@ -288,4 +288,30 @@ void showReadOnlySettings(QWidget *parent, const QString &systemSettingsPath) {
|
||||||
.arg(nativePath));
|
.arg(nativePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showWaylandExperimental(QWidget *parent) {
|
||||||
|
QMessageBox::information(
|
||||||
|
parent, "Experimental feature",
|
||||||
|
QString(
|
||||||
|
"<p>Thanks for trying the beta version!</p>"
|
||||||
|
"<p>Wayland support is experimental and contains bugs.</p>"
|
||||||
|
R"(<p>Please <a href="%1" style="color: %2">report bugs</a> to us if you find any.</p>)"
|
||||||
|
"<p>Happy testing!</p>")
|
||||||
|
.arg(kUrlBugReport, kColorSecondary));
|
||||||
|
}
|
||||||
|
|
||||||
|
void showWaylandLibraryError(QWidget *parent) {
|
||||||
|
QMessageBox::critical(
|
||||||
|
parent, "Library problem",
|
||||||
|
QString(
|
||||||
|
"<p>Sorry, while this version of Synergy does support Wayland, "
|
||||||
|
"this build was not linked with one or more of the required "
|
||||||
|
"libraries.</p>"
|
||||||
|
"<p>Please either switch to X from your login screen or use a build "
|
||||||
|
"that uses the correct libraries.</p>"
|
||||||
|
"<p>If you think this is incorrect, please "
|
||||||
|
R"(<a href="%1" style="color: %2">report a bug</a>.</p>)"
|
||||||
|
"<p>Please check the logs for more information.</p>")
|
||||||
|
.arg(kUrlBugReport, kColorSecondary));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace synergy::gui::messages
|
} // namespace synergy::gui::messages
|
||||||
|
|
|
||||||
|
|
@ -52,4 +52,8 @@ bool showClearSettings(QWidget *parent);
|
||||||
|
|
||||||
void showReadOnlySettings(QWidget *parent, const QString &systemSettingsPath);
|
void showReadOnlySettings(QWidget *parent, const QString &systemSettingsPath);
|
||||||
|
|
||||||
|
void showWaylandExperimental(QWidget *parent);
|
||||||
|
|
||||||
|
void showWaylandLibraryError(QWidget *parent);
|
||||||
|
|
||||||
} // namespace synergy::gui::messages
|
} // namespace synergy::gui::messages
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,7 @@ EiScreen::EiScreen(bool is_primary, IEventQueue *events, bool use_portal)
|
||||||
#if HAVE_LIBPORTAL_INPUTCAPTURE
|
#if HAVE_LIBPORTAL_INPUTCAPTURE
|
||||||
portal_input_capture_ = new PortalInputCapture(this, events_);
|
portal_input_capture_ = new PortalInputCapture(this, events_);
|
||||||
#else
|
#else
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument("missing libportal input capture support");
|
||||||
"Missing libportal InputCapture portal support");
|
|
||||||
#endif // HAVE_LIBPORTAL_INPUTCAPTURE
|
#endif // HAVE_LIBPORTAL_INPUTCAPTURE
|
||||||
} else {
|
} else {
|
||||||
#if WINAPI_LIBPORTAL
|
#if WINAPI_LIBPORTAL
|
||||||
|
|
@ -82,8 +81,7 @@ EiScreen::EiScreen(bool is_primary, IEventQueue *events, bool use_portal)
|
||||||
this, &EiScreen::handle_portal_session_closed));
|
this, &EiScreen::handle_portal_session_closed));
|
||||||
portal_remote_desktop_ = new PortalRemoteDesktop(this, events_);
|
portal_remote_desktop_ = new PortalRemoteDesktop(this, events_);
|
||||||
#else
|
#else
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument("missing libportal remote desktop support");
|
||||||
"Missing libportal RemoteDesktop portal support");
|
|
||||||
#endif // WINAPI_LIBPORTAL
|
#endif // WINAPI_LIBPORTAL
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -91,7 +89,7 @@ EiScreen::EiScreen(bool is_primary, IEventQueue *events, bool use_portal)
|
||||||
auto rc = ei_setup_backend_socket(ei_, nullptr);
|
auto rc = ei_setup_backend_socket(ei_, nullptr);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
LOG_DEBUG("ei init error: %s", strerror(-rc));
|
LOG_DEBUG("ei init error: %s", strerror(-rc));
|
||||||
throw std::runtime_error("Failed to init ei context");
|
throw std::runtime_error("failed to init ei context");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -819,7 +817,7 @@ void EiScreen::updateButtons() {
|
||||||
IKeyState *EiScreen::getKeyState() const { return key_state_; }
|
IKeyState *EiScreen::getKeyState() const { return key_state_; }
|
||||||
|
|
||||||
String EiScreen::getSecureInputApp() const {
|
String EiScreen::getSecureInputApp() const {
|
||||||
throw std::runtime_error("Not implemented");
|
throw std::runtime_error("get security input app not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
EiScreen::HotKeyItem::HotKeyItem(std::uint32_t mask, std::uint32_t id)
|
EiScreen::HotKeyItem::HotKeyItem(std::uint32_t mask, std::uint32_t id)
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ void PortalInputCapture::cb_session_closed(XdpSession *session) {
|
||||||
|
|
||||||
void PortalInputCapture::cb_init_input_capture_session(
|
void PortalInputCapture::cb_init_input_capture_session(
|
||||||
GObject *object, GAsyncResult *res) {
|
GObject *object, GAsyncResult *res) {
|
||||||
LOG_DEBUG("portal session ready");
|
LOG_DEBUG("portal input capture session initialized");
|
||||||
g_autoptr(GError) error = nullptr;
|
g_autoptr(GError) error = nullptr;
|
||||||
|
|
||||||
auto session = xdp_portal_create_input_capture_session_finish(
|
auto session = xdp_portal_create_input_capture_session_finish(
|
||||||
|
|
|
||||||
8
src/lib/platform/PortalRemoteDesktop.cpp
Normal file → Executable file
|
|
@ -94,7 +94,9 @@ void PortalRemoteDesktop::cb_session_started(
|
||||||
auto session = XDP_SESSION(object);
|
auto session = XDP_SESSION(object);
|
||||||
auto success = xdp_session_start_finish(session, res, &error);
|
auto success = xdp_session_start_finish(session, res, &error);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
LOG_ERR("failed to start portal remote desktop session");
|
LOG_ERR(
|
||||||
|
"failed to start portal remote desktop session, quitting: %s",
|
||||||
|
error->message);
|
||||||
g_main_loop_quit(glib_main_loop_);
|
g_main_loop_quit(glib_main_loop_);
|
||||||
events_->addEvent(Event::kQuit);
|
events_->addEvent(Event::kQuit);
|
||||||
return;
|
return;
|
||||||
|
|
@ -123,7 +125,7 @@ void PortalRemoteDesktop::cb_session_started(
|
||||||
|
|
||||||
void PortalRemoteDesktop::cb_init_remote_desktop_session(
|
void PortalRemoteDesktop::cb_init_remote_desktop_session(
|
||||||
GObject *object, GAsyncResult *res) {
|
GObject *object, GAsyncResult *res) {
|
||||||
LOG_DEBUG("remote desktop session ready");
|
LOG_DEBUG("portal remote desktop session initialized");
|
||||||
g_autoptr(GError) error = nullptr;
|
g_autoptr(GError) error = nullptr;
|
||||||
|
|
||||||
auto session = xdp_portal_create_remote_desktop_session_finish(
|
auto session = xdp_portal_create_remote_desktop_session_finish(
|
||||||
|
|
@ -149,7 +151,7 @@ void PortalRemoteDesktop::cb_init_remote_desktop_session(
|
||||||
session_signal_id_ = g_signal_connect(
|
session_signal_id_ = g_signal_connect(
|
||||||
G_OBJECT(session), "closed", G_CALLBACK(cb_session_closed_cb), this);
|
G_OBJECT(session), "closed", G_CALLBACK(cb_session_closed_cb), this);
|
||||||
|
|
||||||
LOG_DEBUG("Session ready, starting");
|
LOG_DEBUG("portal remote desktop session starting");
|
||||||
xdp_session_start(
|
xdp_session_start(
|
||||||
session,
|
session,
|
||||||
nullptr, // parent
|
nullptr, // parent
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,27 @@
|
||||||
|
|
||||||
namespace synergy::platform {
|
namespace synergy::platform {
|
||||||
|
|
||||||
|
#if WINAPI_LIBEI
|
||||||
|
const auto kHasEi = true;
|
||||||
|
#else
|
||||||
|
const auto kHasEi = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WINAPI_LIBPORTAL
|
||||||
|
const auto kHasPortal = true;
|
||||||
|
#else
|
||||||
|
const auto kHasPortal = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBPORTAL_INPUTCAPTURE
|
||||||
|
const auto kHasPortalInputCapture = true;
|
||||||
|
#else
|
||||||
|
const auto kHasPortalInputCapture = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
inline bool isWayland() {
|
inline bool isWayland() {
|
||||||
const std::string session = getenv("XDG_SESSION_TYPE");
|
const auto session = getenv("XDG_SESSION_TYPE");
|
||||||
return session == "wayland";
|
return session != nullptr && std::string(session) == "wayland";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace synergy::platform
|
} // namespace synergy::platform
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
#include "synergy/unix/AppUtilUnix.h"
|
#include "synergy/unix/AppUtilUnix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
class IArchTaskBarReceiver;
|
class IArchTaskBarReceiver;
|
||||||
class BufferedLogOutputter;
|
class BufferedLogOutputter;
|
||||||
class ILogOutputter;
|
class ILogOutputter;
|
||||||
|
|
@ -46,6 +48,11 @@ typedef IArchTaskBarReceiver *(*CreateTaskBarReceiverFunc)(
|
||||||
|
|
||||||
class App : public IApp {
|
class App : public IApp {
|
||||||
public:
|
public:
|
||||||
|
class XNoEiSupport : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
XNoEiSupport() : std::runtime_error("libei is not supported") {}
|
||||||
|
};
|
||||||
|
|
||||||
App(IEventQueue *events, CreateTaskBarReceiverFunc createTaskBarReceiver,
|
App(IEventQueue *events, CreateTaskBarReceiverFunc createTaskBarReceiver,
|
||||||
synergy::ArgsBase *args);
|
synergy::ArgsBase *args);
|
||||||
App(App const &) = delete;
|
App(App const &) = delete;
|
||||||
|
|
|
||||||
|
|
@ -186,13 +186,19 @@ synergy::Screen *ClientApp::createScreen() {
|
||||||
args().m_enableLangSync, args().m_clientScrollDirection),
|
args().m_enableLangSync, args().m_clientScrollDirection),
|
||||||
m_events);
|
m_events);
|
||||||
#endif
|
#endif
|
||||||
#if WINAPI_LIBEI
|
|
||||||
|
#if defined(WINAPI_XWINDOWS) or defined(WINAPI_LIBEI)
|
||||||
if (synergy::platform::isWayland()) {
|
if (synergy::platform::isWayland()) {
|
||||||
|
#if WINAPI_LIBEI
|
||||||
LOG((CLOG_INFO "using ei screen for wayland"));
|
LOG((CLOG_INFO "using ei screen for wayland"));
|
||||||
return new synergy::Screen(
|
return new synergy::Screen(
|
||||||
new synergy::EiScreen(false, m_events, true), m_events);
|
new synergy::EiScreen(false, m_events, true), m_events);
|
||||||
|
#else
|
||||||
|
throw XNoEiSupport();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WINAPI_XWINDOWS
|
#if WINAPI_XWINDOWS
|
||||||
LOG((CLOG_INFO "using legacy x windows screen"));
|
LOG((CLOG_INFO "using legacy x windows screen"));
|
||||||
return new synergy::Screen(
|
return new synergy::Screen(
|
||||||
|
|
@ -202,6 +208,7 @@ synergy::Screen *ClientApp::createScreen() {
|
||||||
m_events);
|
m_events);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WINAPI_CARBON
|
#if WINAPI_CARBON
|
||||||
return new synergy::Screen(
|
return new synergy::Screen(
|
||||||
new OSXScreen(
|
new OSXScreen(
|
||||||
|
|
|
||||||
|
|
@ -560,11 +560,15 @@ synergy::Screen *ServerApp::createScreen() {
|
||||||
m_events);
|
m_events);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WINAPI_LIBEI
|
#if defined(WINAPI_XWINDOWS) or defined(WINAPI_LIBEI)
|
||||||
if (synergy::platform::isWayland()) {
|
if (synergy::platform::isWayland()) {
|
||||||
|
#if WINAPI_LIBEI
|
||||||
LOG((CLOG_INFO "using ei screen for wayland"));
|
LOG((CLOG_INFO "using ei screen for wayland"));
|
||||||
return new synergy::Screen(
|
return new synergy::Screen(
|
||||||
new synergy::EiScreen(true, m_events, true), m_events);
|
new synergy::EiScreen(true, m_events, true), m_events);
|
||||||
|
#else
|
||||||
|
throw XNoEiSupport();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
129
src/test/unittests/gui/core/WaylandWarningsTests.cpp
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2024 Symless Ltd.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gui/core/WaylandWarnings.h"
|
||||||
|
|
||||||
|
#include "gui/core/CoreProcess.h"
|
||||||
|
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
using namespace synergy::gui;
|
||||||
|
using namespace synergy::gui::core;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct MockDeps : public WaylandWarnings::Deps {
|
||||||
|
MOCK_METHOD(void, showWaylandExperimental, (QWidget *), (override));
|
||||||
|
MOCK_METHOD(void, showWaylandLibraryError, (QWidget *), (override));
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(WaylandWarningsTests, showOnce_serverNoEi_showLibraryError) {
|
||||||
|
const auto deps = std::make_shared<MockDeps>();
|
||||||
|
const bool hasEi = false;
|
||||||
|
const bool hasPortal = false;
|
||||||
|
const bool hasPortalIC = false;
|
||||||
|
WaylandWarnings waylandWarnings(deps);
|
||||||
|
|
||||||
|
EXPECT_CALL(*deps, showWaylandLibraryError(nullptr)).Times(1);
|
||||||
|
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Server, hasEi, hasPortal, hasPortalIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WaylandWarningsTests, showOnce_serverNoPortal_showLibraryError) {
|
||||||
|
const auto deps = std::make_shared<MockDeps>();
|
||||||
|
const bool hasEi = true;
|
||||||
|
const bool hasPortal = false;
|
||||||
|
const bool hasPortalIC = false;
|
||||||
|
WaylandWarnings waylandWarnings(deps);
|
||||||
|
|
||||||
|
EXPECT_CALL(*deps, showWaylandLibraryError(nullptr)).Times(1);
|
||||||
|
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Server, hasEi, hasPortal, hasPortalIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WaylandWarningsTests, showOnce_serverNoPortalIc_showLibraryError) {
|
||||||
|
const auto deps = std::make_shared<MockDeps>();
|
||||||
|
const bool hasEi = true;
|
||||||
|
const bool hasPortal = true;
|
||||||
|
const bool hasPortalIC = false;
|
||||||
|
WaylandWarnings waylandWarnings(deps);
|
||||||
|
|
||||||
|
EXPECT_CALL(*deps, showWaylandLibraryError(nullptr)).Times(1);
|
||||||
|
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Server, hasEi, hasPortal, hasPortalIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WaylandWarningTests, showOnce_clientNoPortalIc_showExperimental) {
|
||||||
|
const auto deps = std::make_shared<MockDeps>();
|
||||||
|
const bool hasEi = true;
|
||||||
|
const bool hasPortal = true;
|
||||||
|
const bool hasPortalIC = false;
|
||||||
|
WaylandWarnings waylandWarnings(deps);
|
||||||
|
|
||||||
|
EXPECT_CALL(*deps, showWaylandExperimental(nullptr)).Times(1);
|
||||||
|
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Client, hasEi, hasPortal, hasPortalIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WaylandWarningsTests, showOnce_serverHasPortalIc_showExperimentalOnly) {
|
||||||
|
const auto deps = std::make_shared<MockDeps>();
|
||||||
|
const bool hasEi = true;
|
||||||
|
const bool hasPortal = true;
|
||||||
|
const bool hasPortalIC = true;
|
||||||
|
WaylandWarnings waylandWarnings(deps);
|
||||||
|
|
||||||
|
EXPECT_CALL(*deps, showWaylandExperimental(nullptr)).Times(1);
|
||||||
|
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Server, hasEi, hasPortal, hasPortalIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WaylandWarningsTests, showOnce_failureCalledTwice_messageOnlyShownOnce) {
|
||||||
|
const auto deps = std::make_shared<MockDeps>();
|
||||||
|
const bool hasEi = false;
|
||||||
|
const bool hasPortal = false;
|
||||||
|
const bool hasPortalIC = false;
|
||||||
|
WaylandWarnings waylandWarnings(deps);
|
||||||
|
|
||||||
|
EXPECT_CALL(*deps, showWaylandLibraryError(nullptr)).Times(1);
|
||||||
|
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Server, hasEi, hasPortal, hasPortalIC);
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Server, hasEi, hasPortal, hasPortalIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(WaylandWarningsTests, showOnce_successCalledTwice_messageOnlyShownOnce) {
|
||||||
|
const auto deps = std::make_shared<MockDeps>();
|
||||||
|
const bool hasEi = true;
|
||||||
|
const bool hasPortal = true;
|
||||||
|
const bool hasPortalIC = true;
|
||||||
|
WaylandWarnings waylandWarnings(deps);
|
||||||
|
|
||||||
|
EXPECT_CALL(*deps, showWaylandExperimental(nullptr)).Times(1);
|
||||||
|
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Server, hasEi, hasPortal, hasPortalIC);
|
||||||
|
waylandWarnings.showOnce(
|
||||||
|
nullptr, CoreProcess::Mode::Server, hasEi, hasPortal, hasPortalIC);
|
||||||
|
}
|
||||||