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
|
||||
|
||||
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] |
|
||||
| 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] |
|
||||
| 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
|
||||
|
||||
|
||||
@ -55,6 +55,10 @@ public:
|
||||
inline static const auto UseHooks = QStringLiteral("core/useHooks");
|
||||
inline static const auto Language = QStringLiteral("core/language");
|
||||
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
|
||||
inline static const auto ScreenName = QStringLiteral("core/screenName"); // Replaced By ComputerName
|
||||
@ -207,6 +211,10 @@ private:
|
||||
, Settings::Core::Port
|
||||
, Settings::Core::PreventSleep
|
||||
, Settings::Core::ProcessMode
|
||||
, Settings::Core::EnableEnterCommand
|
||||
, Settings::Core::EnableExitCommand
|
||||
, Settings::Core::ScreenEnterCommand
|
||||
, Settings::Core::ScreenExitCommand
|
||||
, Settings::Core::ScreenName
|
||||
, Settings::Core::ComputerName
|
||||
, Settings::Core::Display
|
||||
@ -250,6 +258,8 @@ private:
|
||||
, Settings::Gui::ShowVersionInTitle
|
||||
, Settings::Core::PreventSleep
|
||||
, Settings::Core::UseWlClipboard
|
||||
, Settings::Core::EnableEnterCommand
|
||||
, Settings::Core::EnableExitCommand
|
||||
, Settings::Server::ExternalConfig
|
||||
, Settings::Client::InvertYScroll
|
||||
, Settings::Client::InvertXScroll
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
#include "base/Log.h"
|
||||
#include "deskflow/IPlatformScreen.h"
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
namespace deskflow {
|
||||
|
||||
//
|
||||
@ -119,6 +121,14 @@ void Screen::enter(KeyModifierMask toggleMask)
|
||||
} else {
|
||||
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()
|
||||
@ -140,6 +150,13 @@ bool 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
|
||||
m_screen->checkClipboards();
|
||||
|
||||
@ -14,6 +14,11 @@
|
||||
#include "OSXHelpers.h"
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <signal.h>
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
@ -203,6 +208,14 @@ void CoreProcess::startForegroundProcess(const QStringList &args)
|
||||
const auto quoted = makeQuotedArgs(m_appPath, args);
|
||||
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);
|
||||
|
||||
if (m_process->waitForStarted()) {
|
||||
|
||||
@ -31,10 +31,9 @@ SettingsDialog::SettingsDialog(QWidget *parent, const IServerConfig &serverConfi
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
// hide advanced options on macOS and portable windows
|
||||
if (deskflow::platform::isMac() || (deskflow::platform::isWindows() && Settings::isPortableMode())) {
|
||||
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabAdvanced));
|
||||
}
|
||||
// these are enabled by the control next to them
|
||||
ui->lineCommandEnter->setEnabled(false);
|
||||
ui->lineCommandExit->setEnabled(false);
|
||||
|
||||
// set up the language combo
|
||||
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();
|
||||
|
||||
adjustSize();
|
||||
@ -95,6 +99,9 @@ void SettingsDialog::initConnections() const
|
||||
&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->groupService, &QGroupBox::toggled, this, &SettingsDialog::updateControls);
|
||||
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->lineLogFilename, &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()
|
||||
@ -224,6 +235,10 @@ void SettingsDialog::accept()
|
||||
Settings::setValue(Settings::Log::GuiDebug, ui->cbGuiDebug->isChecked());
|
||||
Settings::setValue(Settings::Core::UseWlClipboard, ui->cbUseWlClipboard->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;
|
||||
if (ui->groupService->isChecked())
|
||||
@ -247,6 +262,10 @@ void SettingsDialog::loadFromConfig()
|
||||
ui->cbGuiDebug->setChecked(Settings::value(Settings::Log::GuiDebug).toBool());
|
||||
ui->cbUseWlClipboard->setChecked(Settings::value(Settings::Core::UseWlClipboard).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>();
|
||||
ui->groupService->setChecked(processMode == Settings::ProcessMode::Service);
|
||||
@ -356,6 +375,10 @@ void SettingsDialog::updateControls()
|
||||
ui->comboTlsKeyLength->setEnabled(writable);
|
||||
ui->rbCloseToTray->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.
|
||||
// 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->groupSecurity->isChecked() != Settings::value(Settings::Security::TlsEnabled).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());
|
||||
|
||||
if (!ignoreInterface)
|
||||
@ -446,6 +473,10 @@ bool SettingsDialog::isDefault() const
|
||||
(ui->comboTlsKeyLength->currentText() == Settings::defaultValue(Settings::Security::KeySize).toString()) &&
|
||||
(ui->groupSecurity->isChecked() == Settings::defaultValue(Settings::Security::TlsEnabled).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")
|
||||
);
|
||||
}
|
||||
@ -462,6 +493,10 @@ void SettingsDialog::resetToDefault()
|
||||
ui->cbGuiDebug->setChecked(Settings::defaultValue(Settings::Log::GuiDebug).toBool());
|
||||
ui->cbUseWlClipboard->setChecked(Settings::defaultValue(Settings::Core::UseWlClipboard).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();
|
||||
ui->rbCloseToTray->setChecked(autoHide);
|
||||
|
||||
@ -6,33 +6,30 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>564</width>
|
||||
<height>431</height>
|
||||
<width>490</width>
|
||||
<height>366</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="_13">
|
||||
<property name="spacing">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<widget class="QWidget" name="tabGeneral">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>&General</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="spacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
@ -40,13 +37,13 @@
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_6">
|
||||
@ -147,16 +144,16 @@
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_10">
|
||||
<spacer name="verticalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
@ -266,16 +263,16 @@
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_7">
|
||||
<spacer name="verticalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
@ -492,16 +489,16 @@
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_8">
|
||||
<spacer name="verticalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
@ -788,12 +785,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabAdvanced">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>&Advanced</string>
|
||||
</attribute>
|
||||
@ -805,16 +796,16 @@
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>20</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_9">
|
||||
<spacer name="verticalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
@ -831,12 +822,6 @@
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Use background service (daemon)</string>
|
||||
</property>
|
||||
@ -862,12 +847,6 @@
|
||||
</item>
|
||||
<item>
|
||||
<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">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbUseWlClipboard">
|
||||
@ -889,6 +868,42 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2026 Deskflow Developers
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* 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");
|
||||
|
||||
if (!OpenClipboard(m_window)) {
|
||||
LOG_WARN("failed to open clipboard: %d", GetLastError());
|
||||
return false;
|
||||
// The clipboard is a global mutex on Windows. We aren't always going to
|
||||
// get the lock on the first try, so try a few times before giving up.
|
||||
// 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;
|
||||
}
|
||||
|
||||
m_time = time;
|
||||
if (i < kMaxRetries - 1) {
|
||||
LOG_DEBUG("failed to open clipboard (attempt %d/%d, error=%d), retrying", i + 1, kMaxRetries, GetLastError());
|
||||
Sleep(kRetryDelayMs);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
LOG_WARN("failed to open clipboard after %d attempts: %d", kMaxRetries, GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
void MSWindowsClipboard::close() const
|
||||
|
||||
@ -199,7 +199,7 @@ public:
|
||||
|
||||
//! 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.
|
||||
*/
|
||||
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>
|
||||
<translation type="unfinished">Mostrar la ventana principal</translation>
|
||||
</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>
|
||||
<name>StatusBar</name>
|
||||
|
||||
@ -1309,6 +1309,14 @@ L'abilitazione di questa impostazione disabiliterà l'interfaccia graf
|
||||
<source>Show the main window</source>
|
||||
<translation type="unfinished">Mostra la finestra principale</translation>
|
||||
</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>
|
||||
<name>StatusBar</name>
|
||||
|
||||
@ -1311,6 +1311,14 @@ Enabling this setting will disable the server config GUI.</source>
|
||||
<source>Show the main window</source>
|
||||
<translation type="unfinished">メインウィンドウを表示する</translation>
|
||||
</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>
|
||||
<name>StatusBar</name>
|
||||
|
||||
@ -1309,6 +1309,14 @@ Enabling this setting will disable the server config GUI.</source>
|
||||
<source>Show the main window</source>
|
||||
<translation type="unfinished">메인 창을 표시합니다</translation>
|
||||
</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>
|
||||
<name>StatusBar</name>
|
||||
|
||||
@ -1307,6 +1307,14 @@ Enabling this setting will disable the server config GUI.</source>
|
||||
<source>Show the main window</source>
|
||||
<translation type="unfinished">Показать главное окно</translation>
|
||||
</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>
|
||||
<name>StatusBar</name>
|
||||
|
||||
@ -1311,6 +1311,14 @@ Enabling this setting will disable the server config GUI.</source>
|
||||
<source>Show the main window</source>
|
||||
<translation type="unfinished">显示主窗口</translation>
|
||||
</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>
|
||||
<name>StatusBar</name>
|
||||
|
||||
Reference in New Issue
Block a user