Compare commits
10 Commits
6657bdd9b1
...
abaf233a07
| Author | SHA1 | Date | |
|---|---|---|---|
| abaf233a07 | |||
| b251c98a4e | |||
| 23c8496e24 | |||
| 18220a7847 | |||
| a26698c377 | |||
| ac8cc42b7a | |||
| 7126f31d3f | |||
| 44db410dad | |||
| bc7b1082e7 | |||
| ea0bf9d56d |
18
.github/CODE_OF_CONDUCT.md
vendored
Normal file
18
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Deskflow Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We want the Deskflow community to be one where everyone can work together. We pledge to keep our community focused on the project and the code around the project.
|
||||||
|
|
||||||
|
## Community Standards
|
||||||
|
|
||||||
|
* Keep interactions respectful and focused on the project
|
||||||
|
* Contributions are expected to follow the [contribution guide](https://github.com/deskflow/deskflow/wiki/Contributing).
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Enforcement will be done at the descression of the Deskflow Moderators.
|
||||||
|
|
||||||
|
1. Warning
|
||||||
|
2. Temporary ban
|
||||||
|
3. Permanent banning
|
||||||
2
.github/README.md
vendored
2
.github/README.md
vendored
@ -184,4 +184,4 @@ Deskflow is made by possible by these contributors.
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under [GPL-2.0](LICENSE) with an [OpenSSL exception](LICENSES/LicenseRef-OpenSSL-Exception.txt).
|
This project is licensed under [GPL-2.0](LICENSE) with an [OpenSSL exception](../LICENSES/LicenseRef-OpenSSL-Exception.txt).
|
||||||
|
|||||||
@ -77,6 +77,10 @@ This section contains general options it will begin with `[core]`
|
|||||||
| useHooks | `true` or `false` | If Windows uses hooks or not [default: true] |
|
| useHooks | `true` or `false` | If Windows uses hooks or not [default: true] |
|
||||||
| language | 639 language | The language to display the GUI in [default: en] |
|
| language | 639 language | The language to display the GUI in [default: en] |
|
||||||
| wlClipboard | `true` or `false` | When true the wl-clipboard backend will be enabled [default: false] |
|
| wlClipboard | `true` or `false` | When true the wl-clipboard backend will be enabled [default: false] |
|
||||||
|
| enableEnterCommand | `true` or `false` | Should the enter command be triggered when the screen is entered [defaut: false] |
|
||||||
|
| enterCommand | command | A command to run when the screen is entered. |
|
||||||
|
| enableExitCommand | `true` or `false` | Should the exit command be triggered when the screen is exited [defaut: false] |
|
||||||
|
| exitCommand | command | A command to run when the screen is exited. |
|
||||||
|
|
||||||
### Daemon
|
### Daemon
|
||||||
|
|
||||||
|
|||||||
@ -55,6 +55,10 @@ public:
|
|||||||
inline static const auto UseHooks = QStringLiteral("core/useHooks");
|
inline static const auto UseHooks = QStringLiteral("core/useHooks");
|
||||||
inline static const auto Language = QStringLiteral("core/language");
|
inline static const auto Language = QStringLiteral("core/language");
|
||||||
inline static const auto UseWlClipboard = QStringLiteral("core/wlClipboard");
|
inline static const auto UseWlClipboard = QStringLiteral("core/wlClipboard");
|
||||||
|
inline static const auto EnableEnterCommand = QStringLiteral("core/enableEnterCommand");
|
||||||
|
inline static const auto ScreenEnterCommand = QStringLiteral("core/enterCommand");
|
||||||
|
inline static const auto EnableExitCommand = QStringLiteral("core/enableExitCommand");
|
||||||
|
inline static const auto ScreenExitCommand = QStringLiteral("core/exitCommand");
|
||||||
|
|
||||||
// TODO: REMOVE In 2.0
|
// TODO: REMOVE In 2.0
|
||||||
inline static const auto ScreenName = QStringLiteral("core/screenName"); // Replaced By ComputerName
|
inline static const auto ScreenName = QStringLiteral("core/screenName"); // Replaced By ComputerName
|
||||||
@ -207,6 +211,10 @@ private:
|
|||||||
, Settings::Core::Port
|
, Settings::Core::Port
|
||||||
, Settings::Core::PreventSleep
|
, Settings::Core::PreventSleep
|
||||||
, Settings::Core::ProcessMode
|
, Settings::Core::ProcessMode
|
||||||
|
, Settings::Core::EnableEnterCommand
|
||||||
|
, Settings::Core::EnableExitCommand
|
||||||
|
, Settings::Core::ScreenEnterCommand
|
||||||
|
, Settings::Core::ScreenExitCommand
|
||||||
, Settings::Core::ScreenName
|
, Settings::Core::ScreenName
|
||||||
, Settings::Core::ComputerName
|
, Settings::Core::ComputerName
|
||||||
, Settings::Core::Display
|
, Settings::Core::Display
|
||||||
@ -250,6 +258,8 @@ private:
|
|||||||
, Settings::Gui::ShowVersionInTitle
|
, Settings::Gui::ShowVersionInTitle
|
||||||
, Settings::Core::PreventSleep
|
, Settings::Core::PreventSleep
|
||||||
, Settings::Core::UseWlClipboard
|
, Settings::Core::UseWlClipboard
|
||||||
|
, Settings::Core::EnableEnterCommand
|
||||||
|
, Settings::Core::EnableExitCommand
|
||||||
, Settings::Server::ExternalConfig
|
, Settings::Server::ExternalConfig
|
||||||
, Settings::Client::InvertYScroll
|
, Settings::Client::InvertYScroll
|
||||||
, Settings::Client::InvertXScroll
|
, Settings::Client::InvertXScroll
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "deskflow/IPlatformScreen.h"
|
#include "deskflow/IPlatformScreen.h"
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
namespace deskflow {
|
namespace deskflow {
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -119,6 +121,14 @@ void Screen::enter(KeyModifierMask toggleMask)
|
|||||||
} else {
|
} else {
|
||||||
enterSecondary(toggleMask);
|
enterSecondary(toggleMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Settings::value(Settings::Core::EnableEnterCommand).toBool()) {
|
||||||
|
auto args = QProcess::splitCommand(Settings::value(Settings::Core::ScreenEnterCommand).toString());
|
||||||
|
const auto command = args.takeFirst();
|
||||||
|
LOG_DEBUG("running screen enter command: %s %s", qPrintable(command), qPrintable(args.join(" ")));
|
||||||
|
if (!QProcess::startDetached(command, args))
|
||||||
|
LOG_ERR("failed to run screen enter command");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Screen::leave()
|
bool Screen::leave()
|
||||||
@ -140,6 +150,13 @@ bool Screen::leave()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_screen->leave();
|
m_screen->leave();
|
||||||
|
if (Settings::value(Settings::Core::EnableExitCommand).toBool()) {
|
||||||
|
auto args = QProcess::splitCommand(Settings::value(Settings::Core::ScreenExitCommand).toString());
|
||||||
|
const auto command = args.takeFirst();
|
||||||
|
LOG_DEBUG("running screen exit command: %s %s", qPrintable(command), qPrintable(args.join(" ")));
|
||||||
|
if (!QProcess::startDetached(command, args))
|
||||||
|
LOG_ERR("failed to run screen exit command");
|
||||||
|
}
|
||||||
|
|
||||||
// make sure our idea of clipboard ownership is correct
|
// make sure our idea of clipboard ownership is correct
|
||||||
m_screen->checkClipboards();
|
m_screen->checkClipboards();
|
||||||
|
|||||||
@ -14,6 +14,11 @@
|
|||||||
#include "OSXHelpers.h"
|
#include "OSXHelpers.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@ -203,6 +208,14 @@ void CoreProcess::startForegroundProcess(const QStringList &args)
|
|||||||
const auto quoted = makeQuotedArgs(m_appPath, args);
|
const auto quoted = makeQuotedArgs(m_appPath, args);
|
||||||
qInfo("running command: %s", qPrintable(quoted));
|
qInfo("running command: %s", qPrintable(quoted));
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
m_process->setChildProcessModifier([] {
|
||||||
|
// the core process becomes orphaned when the gui process exits abruptly (e.g. with kill -9),
|
||||||
|
// so ensure the os also kills the core when that happens to the gui.
|
||||||
|
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
m_process->start(m_appPath, args);
|
m_process->start(m_appPath, args);
|
||||||
|
|
||||||
if (m_process->waitForStarted()) {
|
if (m_process->waitForStarted()) {
|
||||||
|
|||||||
@ -31,10 +31,9 @@ SettingsDialog::SettingsDialog(QWidget *parent, const IServerConfig &serverConfi
|
|||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
// hide advanced options on macOS and portable windows
|
// these are enabled by the control next to them
|
||||||
if (deskflow::platform::isMac() || (deskflow::platform::isWindows() && Settings::isPortableMode())) {
|
ui->lineCommandEnter->setEnabled(false);
|
||||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabAdvanced));
|
ui->lineCommandExit->setEnabled(false);
|
||||||
}
|
|
||||||
|
|
||||||
// set up the language combo
|
// set up the language combo
|
||||||
I18N::reDetectLanguages();
|
I18N::reDetectLanguages();
|
||||||
@ -63,6 +62,11 @@ SettingsDialog::SettingsDialog(QWidget *parent, const IServerConfig &serverConfi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const auto interface = Settings::value(Settings::Core::Interface).toString();
|
||||||
|
!interface.isEmpty() && (ui->comboInterface->findData(interface) == -1)) {
|
||||||
|
ui->comboInterface->addItem(interface, interface);
|
||||||
|
}
|
||||||
|
|
||||||
loadFromConfig();
|
loadFromConfig();
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
@ -95,6 +99,9 @@ void SettingsDialog::initConnections() const
|
|||||||
&SettingsDialog::resetToDefault
|
&SettingsDialog::resetToDefault
|
||||||
);
|
);
|
||||||
|
|
||||||
|
connect(ui->cbRunEnterCommand, &QCheckBox::toggled, ui->lineCommandEnter, &QLineEdit::setEnabled);
|
||||||
|
connect(ui->cbRunExitCommand, &QCheckBox::toggled, ui->lineCommandExit, &QLineEdit::setEnabled);
|
||||||
|
|
||||||
connect(ui->groupSecurity, &QGroupBox::toggled, this, &SettingsDialog::updateTlsControlsEnabled);
|
connect(ui->groupSecurity, &QGroupBox::toggled, this, &SettingsDialog::updateTlsControlsEnabled);
|
||||||
connect(ui->groupService, &QGroupBox::toggled, this, &SettingsDialog::updateControls);
|
connect(ui->groupService, &QGroupBox::toggled, this, &SettingsDialog::updateControls);
|
||||||
connect(ui->btnTlsRegenCert, &QPushButton::clicked, this, &SettingsDialog::regenCertificates);
|
connect(ui->btnTlsRegenCert, &QPushButton::clicked, this, &SettingsDialog::regenCertificates);
|
||||||
@ -129,6 +136,10 @@ void SettingsDialog::initConnections() const
|
|||||||
connect(ui->groupSecurity, &QGroupBox::toggled, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
connect(ui->groupSecurity, &QGroupBox::toggled, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
||||||
connect(ui->lineLogFilename, &QLineEdit::textChanged, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
connect(ui->lineLogFilename, &QLineEdit::textChanged, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
||||||
connect(ui->lineTlsCertPath, &QLineEdit::textChanged, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
connect(ui->lineTlsCertPath, &QLineEdit::textChanged, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
||||||
|
connect(ui->cbRunEnterCommand, &QCheckBox::toggled, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
||||||
|
connect(ui->cbRunExitCommand, &QCheckBox::toggled, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
||||||
|
connect(ui->lineCommandEnter, &QLineEdit::textChanged, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
||||||
|
connect(ui->lineCommandExit, &QLineEdit::textChanged, this, &SettingsDialog::setButtonBoxEnabledButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsDialog::regenCertificates()
|
void SettingsDialog::regenCertificates()
|
||||||
@ -224,6 +235,10 @@ void SettingsDialog::accept()
|
|||||||
Settings::setValue(Settings::Log::GuiDebug, ui->cbGuiDebug->isChecked());
|
Settings::setValue(Settings::Log::GuiDebug, ui->cbGuiDebug->isChecked());
|
||||||
Settings::setValue(Settings::Core::UseWlClipboard, ui->cbUseWlClipboard->isChecked());
|
Settings::setValue(Settings::Core::UseWlClipboard, ui->cbUseWlClipboard->isChecked());
|
||||||
Settings::setValue(Settings::Gui::ShowVersionInTitle, ui->cbShowVersion->isChecked());
|
Settings::setValue(Settings::Gui::ShowVersionInTitle, ui->cbShowVersion->isChecked());
|
||||||
|
Settings::setValue(Settings::Core::EnableEnterCommand, ui->cbRunEnterCommand->isChecked());
|
||||||
|
Settings::setValue(Settings::Core::EnableExitCommand, ui->cbRunExitCommand->isChecked());
|
||||||
|
Settings::setValue(Settings::Core::ScreenEnterCommand, ui->lineCommandEnter->text());
|
||||||
|
Settings::setValue(Settings::Core::ScreenExitCommand, ui->lineCommandExit->text());
|
||||||
|
|
||||||
Settings::ProcessMode mode;
|
Settings::ProcessMode mode;
|
||||||
if (ui->groupService->isChecked())
|
if (ui->groupService->isChecked())
|
||||||
@ -247,6 +262,10 @@ void SettingsDialog::loadFromConfig()
|
|||||||
ui->cbGuiDebug->setChecked(Settings::value(Settings::Log::GuiDebug).toBool());
|
ui->cbGuiDebug->setChecked(Settings::value(Settings::Log::GuiDebug).toBool());
|
||||||
ui->cbUseWlClipboard->setChecked(Settings::value(Settings::Core::UseWlClipboard).toBool());
|
ui->cbUseWlClipboard->setChecked(Settings::value(Settings::Core::UseWlClipboard).toBool());
|
||||||
ui->cbShowVersion->setChecked(Settings::value(Settings::Gui::ShowVersionInTitle).toBool());
|
ui->cbShowVersion->setChecked(Settings::value(Settings::Gui::ShowVersionInTitle).toBool());
|
||||||
|
ui->cbRunEnterCommand->setChecked(Settings::value(Settings::Core::EnableEnterCommand).toBool());
|
||||||
|
ui->cbRunExitCommand->setChecked(Settings::value(Settings::Core::EnableExitCommand).toBool());
|
||||||
|
ui->lineCommandEnter->setText(Settings::value(Settings::Core::ScreenEnterCommand).toString());
|
||||||
|
ui->lineCommandExit->setText(Settings::value(Settings::Core::ScreenExitCommand).toString());
|
||||||
|
|
||||||
const auto processMode = Settings::value(Settings::Core::ProcessMode).value<Settings::ProcessMode>();
|
const auto processMode = Settings::value(Settings::Core::ProcessMode).value<Settings::ProcessMode>();
|
||||||
ui->groupService->setChecked(processMode == Settings::ProcessMode::Service);
|
ui->groupService->setChecked(processMode == Settings::ProcessMode::Service);
|
||||||
@ -356,6 +375,10 @@ void SettingsDialog::updateControls()
|
|||||||
ui->comboTlsKeyLength->setEnabled(writable);
|
ui->comboTlsKeyLength->setEnabled(writable);
|
||||||
ui->rbCloseToTray->setEnabled(writable);
|
ui->rbCloseToTray->setEnabled(writable);
|
||||||
ui->rbExitOnClose->setEnabled(writable);
|
ui->rbExitOnClose->setEnabled(writable);
|
||||||
|
ui->cbRunEnterCommand->setEnabled(writable);
|
||||||
|
ui->cbRunExitCommand->setEnabled(writable);
|
||||||
|
ui->lineCommandEnter->setEnabled(writable && ui->cbRunEnterCommand->isChecked());
|
||||||
|
ui->lineCommandExit->setEnabled(writable && ui->cbRunExitCommand->isChecked());
|
||||||
|
|
||||||
// Portable mode only ever applies to Windows.
|
// Portable mode only ever applies to Windows.
|
||||||
// Daemon options should only be available on Windows when *not* in portable mode.
|
// Daemon options should only be available on Windows when *not* in portable mode.
|
||||||
@ -415,6 +438,10 @@ bool SettingsDialog::isModified() const
|
|||||||
(ui->comboTlsKeyLength->currentText() != Settings::value(Settings::Security::KeySize).toString()) ||
|
(ui->comboTlsKeyLength->currentText() != Settings::value(Settings::Security::KeySize).toString()) ||
|
||||||
(ui->groupSecurity->isChecked() != Settings::value(Settings::Security::TlsEnabled).toBool()) ||
|
(ui->groupSecurity->isChecked() != Settings::value(Settings::Security::TlsEnabled).toBool()) ||
|
||||||
(ui->cbRequireClientCert->isChecked() != Settings::value(Settings::Security::CheckPeers).toBool()) ||
|
(ui->cbRequireClientCert->isChecked() != Settings::value(Settings::Security::CheckPeers).toBool()) ||
|
||||||
|
(ui->cbRunEnterCommand->isChecked() != Settings::value(Settings::Core::EnableEnterCommand).toBool()) ||
|
||||||
|
(ui->cbRunExitCommand->isChecked() != Settings::value(Settings::Core::EnableExitCommand).toBool()) ||
|
||||||
|
(ui->lineCommandEnter->text() != Settings::value(Settings::Core::ScreenEnterCommand).toString()) ||
|
||||||
|
(ui->lineCommandExit->text() != Settings::value(Settings::Core::ScreenExitCommand).toString()) ||
|
||||||
(I18N::nativeTo639Name(ui->comboLanguage->currentText()) != Settings::value(Settings::Core::Language).toString());
|
(I18N::nativeTo639Name(ui->comboLanguage->currentText()) != Settings::value(Settings::Core::Language).toString());
|
||||||
|
|
||||||
if (!ignoreInterface)
|
if (!ignoreInterface)
|
||||||
@ -446,6 +473,10 @@ bool SettingsDialog::isDefault() const
|
|||||||
(ui->comboTlsKeyLength->currentText() == Settings::defaultValue(Settings::Security::KeySize).toString()) &&
|
(ui->comboTlsKeyLength->currentText() == Settings::defaultValue(Settings::Security::KeySize).toString()) &&
|
||||||
(ui->groupSecurity->isChecked() == Settings::defaultValue(Settings::Security::TlsEnabled).toBool()) &&
|
(ui->groupSecurity->isChecked() == Settings::defaultValue(Settings::Security::TlsEnabled).toBool()) &&
|
||||||
(ui->cbRequireClientCert->isChecked() == Settings::defaultValue(Settings::Security::CheckPeers).toBool()) &&
|
(ui->cbRequireClientCert->isChecked() == Settings::defaultValue(Settings::Security::CheckPeers).toBool()) &&
|
||||||
|
(ui->lineCommandEnter->text() == Settings::defaultValue(Settings::Core::ScreenEnterCommand).toString()) &&
|
||||||
|
(ui->lineCommandExit->text() == Settings::defaultValue(Settings::Core::ScreenExitCommand).toString()) &&
|
||||||
|
(ui->cbRunEnterCommand->isChecked() == Settings::defaultValue(Settings::Core::EnableEnterCommand).toBool()) &&
|
||||||
|
(ui->cbRunExitCommand->isChecked() == Settings::defaultValue(Settings::Core::EnableExitCommand).toBool()) &&
|
||||||
(ui->comboLanguage->currentText() == "English")
|
(ui->comboLanguage->currentText() == "English")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -462,6 +493,10 @@ void SettingsDialog::resetToDefault()
|
|||||||
ui->cbGuiDebug->setChecked(Settings::defaultValue(Settings::Log::GuiDebug).toBool());
|
ui->cbGuiDebug->setChecked(Settings::defaultValue(Settings::Log::GuiDebug).toBool());
|
||||||
ui->cbUseWlClipboard->setChecked(Settings::defaultValue(Settings::Core::UseWlClipboard).toBool());
|
ui->cbUseWlClipboard->setChecked(Settings::defaultValue(Settings::Core::UseWlClipboard).toBool());
|
||||||
ui->cbShowVersion->setChecked(Settings::defaultValue(Settings::Gui::ShowVersionInTitle).toBool());
|
ui->cbShowVersion->setChecked(Settings::defaultValue(Settings::Gui::ShowVersionInTitle).toBool());
|
||||||
|
ui->cbRunEnterCommand->setChecked(Settings::defaultValue(Settings::Core::EnableEnterCommand).toBool());
|
||||||
|
ui->cbRunExitCommand->setChecked(Settings::defaultValue(Settings::Core::EnableExitCommand).toBool());
|
||||||
|
ui->lineCommandEnter->setText(Settings::defaultValue(Settings::Core::ScreenEnterCommand).toString());
|
||||||
|
ui->lineCommandExit->setText(Settings::defaultValue(Settings::Core::ScreenExitCommand).toString());
|
||||||
|
|
||||||
const auto autoHide = Settings::defaultValue(Settings::Gui::Autohide).toBool();
|
const auto autoHide = Settings::defaultValue(Settings::Gui::Autohide).toBool();
|
||||||
ui->rbCloseToTray->setChecked(autoHide);
|
ui->rbCloseToTray->setChecked(autoHide);
|
||||||
|
|||||||
@ -6,33 +6,30 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>564</width>
|
<width>490</width>
|
||||||
<height>431</height>
|
<height>366</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Preferences</string>
|
<string>Preferences</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="_13">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<property name="spacing">
|
|
||||||
<number>20</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<widget class="QWidget" name="tabGeneral">
|
<widget class="QWidget" name="tabGeneral">
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>&General</string>
|
<string>&General</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>9</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
@ -40,13 +37,13 @@
|
|||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_6">
|
<spacer name="verticalSpacer_6">
|
||||||
@ -147,16 +144,16 @@
|
|||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_10">
|
<spacer name="verticalSpacer_7">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Orientation::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -266,16 +263,16 @@
|
|||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_7">
|
<spacer name="verticalSpacer_8">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Orientation::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -492,16 +489,16 @@
|
|||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_8">
|
<spacer name="verticalSpacer_9">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Orientation::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -788,12 +785,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="tabAdvanced">
|
<widget class="QWidget" name="tabAdvanced">
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>&Advanced</string>
|
<string>&Advanced</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
@ -805,16 +796,16 @@
|
|||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>12</number>
|
<number>12</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>20</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_9">
|
<spacer name="verticalSpacer_10">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Orientation::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -831,12 +822,6 @@
|
|||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Use background service (daemon)</string>
|
<string>Use background service (daemon)</string>
|
||||||
</property>
|
</property>
|
||||||
@ -862,12 +847,6 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widgetWlClipboard" native="true">
|
<widget class="QWidget" name="widgetWlClipboard" native="true">
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cbUseWlClipboard">
|
<widget class="QCheckBox" name="cbUseWlClipboard">
|
||||||
@ -889,6 +868,42 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout_3">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::FieldGrowthPolicy::ExpandingFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<property name="rowWrapPolicy">
|
||||||
|
<enum>QFormLayout::RowWrapPolicy::DontWrapRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="labelAlignment">
|
||||||
|
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="formAlignment">
|
||||||
|
<set>Qt::AlignmentFlag::AlignHCenter|Qt::AlignmentFlag::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="cbRunEnterCommand">
|
||||||
|
<property name="text">
|
||||||
|
<string>Run command on enter</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineCommandEnter"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="cbRunExitCommand">
|
||||||
|
<property name="text">
|
||||||
|
<string>Run command on exit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineCommandExit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Deskflow -- mouse and keyboard sharing utility
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
|
* SPDX-FileCopyrightText: (C) 2026 Deskflow Developers
|
||||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
@ -116,14 +117,26 @@ bool MSWindowsClipboard::open(Time time) const
|
|||||||
{
|
{
|
||||||
LOG_DEBUG("open clipboard");
|
LOG_DEBUG("open clipboard");
|
||||||
|
|
||||||
if (!OpenClipboard(m_window)) {
|
// The clipboard is a global mutex on Windows. We aren't always going to
|
||||||
LOG_WARN("failed to open clipboard: %d", GetLastError());
|
// get the lock on the first try, so try a few times before giving up.
|
||||||
return false;
|
// Based on Chromium's ScopedClipboard::Acquire() retry loop.
|
||||||
|
static const int kMaxRetries = 5;
|
||||||
|
static const int kRetryDelayMs = 5;
|
||||||
|
|
||||||
|
for (int i = 0; i < kMaxRetries; ++i) {
|
||||||
|
if (OpenClipboard(m_window)) {
|
||||||
|
m_time = time;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < kMaxRetries - 1) {
|
||||||
|
LOG_DEBUG("failed to open clipboard (attempt %d/%d, error=%d), retrying", i + 1, kMaxRetries, GetLastError());
|
||||||
|
Sleep(kRetryDelayMs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_time = time;
|
LOG_WARN("failed to open clipboard after %d attempts: %d", kMaxRetries, GetLastError());
|
||||||
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSWindowsClipboard::close() const
|
void MSWindowsClipboard::close() const
|
||||||
|
|||||||
@ -199,7 +199,7 @@ public:
|
|||||||
|
|
||||||
//! Add screen
|
//! Add screen
|
||||||
/*!
|
/*!
|
||||||
Adds a screen, returning true iff successful. If a screen or
|
Adds a screen, returning true if successful. If a screen or
|
||||||
alias with the given name exists then it fails.
|
alias with the given name exists then it fails.
|
||||||
*/
|
*/
|
||||||
bool addScreen(const std::string &name);
|
bool addScreen(const std::string &name);
|
||||||
|
|||||||
@ -1309,6 +1309,14 @@ Al habilitar esta opción, se deshabilitará la interfaz gráfica de usuario (GU
|
|||||||
<source>Show the main window</source>
|
<source>Show the main window</source>
|
||||||
<translation type="unfinished">Mostrar la ventana principal</translation>
|
<translation type="unfinished">Mostrar la ventana principal</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on enter</source>
|
||||||
|
<translation type="unfinished">Ejecutar comando al presionar Enter</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on exit</source>
|
||||||
|
<translation type="unfinished">Ejecutar comando al salir</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StatusBar</name>
|
<name>StatusBar</name>
|
||||||
|
|||||||
@ -1309,6 +1309,14 @@ L'abilitazione di questa impostazione disabiliterà l'interfaccia graf
|
|||||||
<source>Show the main window</source>
|
<source>Show the main window</source>
|
||||||
<translation type="unfinished">Mostra la finestra principale</translation>
|
<translation type="unfinished">Mostra la finestra principale</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on enter</source>
|
||||||
|
<translation type="unfinished">Esegui il comando alla pressione di Invio</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on exit</source>
|
||||||
|
<translation type="unfinished">Esegui comando all'uscita</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StatusBar</name>
|
<name>StatusBar</name>
|
||||||
|
|||||||
@ -1311,6 +1311,14 @@ Enabling this setting will disable the server config GUI.</source>
|
|||||||
<source>Show the main window</source>
|
<source>Show the main window</source>
|
||||||
<translation type="unfinished">メインウィンドウを表示する</translation>
|
<translation type="unfinished">メインウィンドウを表示する</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on enter</source>
|
||||||
|
<translation type="unfinished">Enterキーでコマンドを実行</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on exit</source>
|
||||||
|
<translation type="unfinished">終了時にコマンドを実行</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StatusBar</name>
|
<name>StatusBar</name>
|
||||||
|
|||||||
@ -1309,6 +1309,14 @@ Enabling this setting will disable the server config GUI.</source>
|
|||||||
<source>Show the main window</source>
|
<source>Show the main window</source>
|
||||||
<translation type="unfinished">메인 창을 표시합니다</translation>
|
<translation type="unfinished">메인 창을 표시합니다</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on enter</source>
|
||||||
|
<translation type="unfinished">Enter 키를 누르면 명령 실행</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on exit</source>
|
||||||
|
<translation type="unfinished">종료 시 명령 실행</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StatusBar</name>
|
<name>StatusBar</name>
|
||||||
|
|||||||
@ -1307,6 +1307,14 @@ Enabling this setting will disable the server config GUI.</source>
|
|||||||
<source>Show the main window</source>
|
<source>Show the main window</source>
|
||||||
<translation type="unfinished">Показать главное окно</translation>
|
<translation type="unfinished">Показать главное окно</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on enter</source>
|
||||||
|
<translation type="unfinished">Выполнять команду по нажатию Enter</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on exit</source>
|
||||||
|
<translation type="unfinished">Выполнить команду при выходе</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StatusBar</name>
|
<name>StatusBar</name>
|
||||||
|
|||||||
@ -1311,6 +1311,14 @@ Enabling this setting will disable the server config GUI.</source>
|
|||||||
<source>Show the main window</source>
|
<source>Show the main window</source>
|
||||||
<translation type="unfinished">显示主窗口</translation>
|
<translation type="unfinished">显示主窗口</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on enter</source>
|
||||||
|
<translation type="unfinished">按下回车键执行命令</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Run command on exit</source>
|
||||||
|
<translation type="unfinished">退出时运行命令</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StatusBar</name>
|
<name>StatusBar</name>
|
||||||
|
|||||||
Reference in New Issue
Block a user