feat: remove stopOnDeskSwitch, its broken

This commit is contained in:
sithlord48 2025-04-06 10:35:53 -04:00 committed by Nick Bolton
parent 9addada64c
commit 71b6f07220
16 changed files with 16 additions and 201 deletions

View file

@ -30,30 +30,6 @@ int main(int argc, char **argv)
Log log; Log log;
EventQueue events; EventQueue events;
// HACK: the `--active-desktop` arg actually belongs in the `deskflow-core` binary,
// but we are placing it here in the server binary temporarily until we are ready to
// ship the `deskflow-core` binary. we are deliberately not integrating `--active-desktop`
// into the existing `ServerApp` arg parsing code as that would be a waste of time.
#if SYSAPI_WIN32
for (int i = 1; i < argc; ++i) {
std::string arg(argv[i]);
// This is called by the daemon (running in session 0) when it needs to know the name of the
// interactive desktop.
// It is necessary to run a utility process because the daemon runs in session 0, which does not
// have access to the active desktop, and so cannot query it's name.
if (arg == "--active-desktop") {
const auto name = ArchMiscWindows::getActiveDesktopName();
if (name.empty()) {
LOG((CLOG_CRIT "failed to get active desktop name"));
return kExitFailed;
}
LOG((CLOG_PRINT "%s", name.c_str()));
return kExitSuccess;
}
}
#endif
ServerApp app(&events); ServerApp app(&events);
return app.run(argc, argv); return app.run(argc, argv);
} }

View file

@ -75,8 +75,7 @@ void Settings::cleanSettings()
QVariant Settings::defaultValue(const QString &key) QVariant Settings::defaultValue(const QString &key)
{ {
if ((key == Gui::Autohide) || (key == Core::StartedBefore) || (key == Core::PreventSleep) || if ((key == Gui::Autohide) || (key == Core::StartedBefore) || (key == Core::PreventSleep) ||
(key == Server::ExternalConfig) || (key == Client::InvertScrollDirection) || (key == Log::ToFile) || (key == Server::ExternalConfig) || (key == Client::InvertScrollDirection) || (key == Log::ToFile)) {
(key == Core::StopOnDeskSwitch)) {
return false; return false;
} }

View file

@ -47,7 +47,6 @@ public:
inline static const auto PreventSleep = QStringLiteral("core/preventSleep"); inline static const auto PreventSleep = QStringLiteral("core/preventSleep");
inline static const auto ProcessMode = QStringLiteral("core/processMode"); inline static const auto ProcessMode = QStringLiteral("core/processMode");
inline static const auto ScreenName = QStringLiteral("core/screenName"); inline static const auto ScreenName = QStringLiteral("core/screenName");
inline static const auto StopOnDeskSwitch = QStringLiteral("core/stopOnDeskSwitch");
inline static const auto StartedBefore = QStringLiteral("core/startedBefore"); inline static const auto StartedBefore = QStringLiteral("core/startedBefore");
inline static const auto UpdateUrl = QStringLiteral("core/updateUrl"); inline static const auto UpdateUrl = QStringLiteral("core/updateUrl");
}; };
@ -166,7 +165,6 @@ private:
, Settings::Core::ProcessMode , Settings::Core::ProcessMode
, Settings::Core::ScreenName , Settings::Core::ScreenName
, Settings::Core::StartedBefore , Settings::Core::StartedBefore
, Settings::Core::StopOnDeskSwitch
, Settings::Core::UpdateUrl , Settings::Core::UpdateUrl
, Settings::Daemon::Command , Settings::Daemon::Command
, Settings::Daemon::Elevate , Settings::Daemon::Elevate

View file

@ -120,16 +120,10 @@ bool ArgParser::parsePlatformArgs(
deskflow::ArgsBase &argsBase, const int &argc, const char *const *argv, int &i, bool isServer deskflow::ArgsBase &argsBase, const int &argc, const char *const *argv, int &i, bool isServer
) )
{ {
#if WINAPI_MSWINDOWS #if !WINAPI_XWINDOWS
if (isArg(i, argc, argv, nullptr, "--stop-on-desk-switch")) { // no options for carbon or windows
argsBase.m_stopOnDeskSwitch = true; return false;
} else { #else
// option not supported here
return false;
}
return true;
#elif WINAPI_XWINDOWS
if (isArg(i, argc, argv, "-display", "--display", 1)) { if (isArg(i, argc, argv, "-display", "--display", 1)) {
// use alternative display // use alternative display
@ -146,9 +140,6 @@ bool ArgParser::parsePlatformArgs(
} }
return true; return true;
#elif WINAPI_CARBON
// no options for carbon
return false;
#endif #endif
} }

View file

@ -80,10 +80,6 @@ public:
/// @brief Stop this computer from sleeping /// @brief Stop this computer from sleeping
bool m_preventSleep = false; bool m_preventSleep = false;
#if SYSAPI_WIN32
bool m_stopOnDeskSwitch = false;
#endif
#if WINAPI_XWINDOWS #if WINAPI_XWINDOWS
bool m_disableXInitThreads = false; bool m_disableXInitThreads = false;
#endif #endif

View file

@ -171,10 +171,7 @@ deskflow::Screen *ClientApp::createScreen()
{ {
#if WINAPI_MSWINDOWS #if WINAPI_MSWINDOWS
return new deskflow::Screen( return new deskflow::Screen(
new MSWindowsScreen( new MSWindowsScreen(false, args().m_noHooks, m_events, args().m_enableLangSync, args().m_clientScrollDirection),
false, args().m_noHooks, args().m_stopOnDeskSwitch, m_events, args().m_enableLangSync,
args().m_clientScrollDirection
),
m_events m_events
); );
#endif #endif

View file

@ -561,9 +561,7 @@ bool ServerApp::startServer()
deskflow::Screen *ServerApp::createScreen() deskflow::Screen *ServerApp::createScreen()
{ {
#if WINAPI_MSWINDOWS #if WINAPI_MSWINDOWS
return new deskflow::Screen( return new deskflow::Screen(new MSWindowsScreen(true, args().m_noHooks, m_events), m_events);
new MSWindowsScreen(true, args().m_noHooks, args().m_stopOnDeskSwitch, m_events), m_events
);
#endif #endif
#if defined(WINAPI_XWINDOWS) or defined(WINAPI_LIBEI) #if defined(WINAPI_XWINDOWS) or defined(WINAPI_LIBEI)

View file

@ -457,23 +457,6 @@ bool CoreProcess::addGenericArgs(QStringList &args, const ProcessMode processMod
args << "--name" << Settings::value(Settings::Core::ScreenName).toString(); args << "--name" << Settings::value(Settings::Core::ScreenName).toString();
if (processMode != ProcessMode::Desktop) {
#if defined(Q_OS_WIN)
// tell the client/server to shut down when a ms windows desk
// is switched; this is because we may need to elevate or not
// based on which desk the user is in (login always needs
// elevation, where as default desk does not).
// Note that this is only enabled when deskflow is set to elevate
// 'as needed' (e.g. on a UAC dialog popup) in order to prevent
// unnecessary restarts when deskflow was started elevated or
// when it is not allowed to elevate. In these cases restarting
// the server is fruitless.
if (Settings::value(Settings::Core::StopOnDeskSwitch).toBool()) {
args << "--stop-on-desk-switch";
}
#endif
}
#ifndef Q_OS_LINUX #ifndef Q_OS_LINUX
if (m_serverConfig.enableDragAndDrop()) { if (m_serverConfig.enableDragAndDrop()) {

View file

@ -68,25 +68,6 @@ void SettingsDialog::initConnections()
connect(ui->btnTlsCertPath, &QPushButton::clicked, this, &SettingsDialog::browseCertificatePath); connect(ui->btnTlsCertPath, &QPushButton::clicked, this, &SettingsDialog::browseCertificatePath);
connect(ui->btnBrowseLog, &QPushButton::clicked, this, &SettingsDialog::browseLogPath); connect(ui->btnBrowseLog, &QPushButton::clicked, this, &SettingsDialog::browseLogPath);
connect(ui->cbLogToFile, &QCheckBox::toggled, this, &SettingsDialog::setLogToFile); connect(ui->cbLogToFile, &QCheckBox::toggled, this, &SettingsDialog::setLogToFile);
connect(ui->cbElevateDaemon, &QCheckBox::toggled, this, [&](bool checked) {
if (!checked)
return;
if (ui->cbStopOnDeskSwitch->isChecked()) {
blockSignals(true);
ui->cbStopOnDeskSwitch->setChecked(false);
blockSignals(false);
}
});
connect(ui->cbStopOnDeskSwitch, &QCheckBox::toggled, this, [&](bool checked) {
if (!checked)
return;
if (ui->cbElevateDaemon->isChecked()) {
blockSignals(true);
ui->cbElevateDaemon->setChecked(false);
blockSignals(false);
}
});
} }
void SettingsDialog::regenCertificates() void SettingsDialog::regenCertificates()
@ -151,7 +132,6 @@ void SettingsDialog::accept()
Settings::setValue(Settings::Log::Level, ui->comboLogLevel->currentIndex()); Settings::setValue(Settings::Log::Level, ui->comboLogLevel->currentIndex());
Settings::setValue(Settings::Log::ToFile, ui->cbLogToFile->isChecked()); Settings::setValue(Settings::Log::ToFile, ui->cbLogToFile->isChecked());
Settings::setValue(Settings::Log::File, ui->lineLogFilename->text()); Settings::setValue(Settings::Log::File, ui->lineLogFilename->text());
Settings::setValue(Settings::Core::StopOnDeskSwitch, ui->cbStopOnDeskSwitch->isChecked());
Settings::setValue(Settings::Daemon::Elevate, ui->cbElevateDaemon->isChecked()); Settings::setValue(Settings::Daemon::Elevate, ui->cbElevateDaemon->isChecked());
Settings::setValue(Settings::Gui::Autohide, ui->cbAutoHide->isChecked()); Settings::setValue(Settings::Gui::Autohide, ui->cbAutoHide->isChecked());
Settings::setValue(Settings::Gui::AutoUpdateCheck, ui->cbAutoUpdate->isChecked()); Settings::setValue(Settings::Gui::AutoUpdateCheck, ui->cbAutoUpdate->isChecked());
@ -187,7 +167,6 @@ void SettingsDialog::loadFromConfig()
ui->cbLanguageSync->setChecked(Settings::value(Settings::Client::LanguageSync).toBool()); ui->cbLanguageSync->setChecked(Settings::value(Settings::Client::LanguageSync).toBool());
ui->cbScrollDirection->setChecked(Settings::value(Settings::Client::InvertScrollDirection).toBool()); ui->cbScrollDirection->setChecked(Settings::value(Settings::Client::InvertScrollDirection).toBool());
ui->cbCloseToTray->setChecked(Settings::value(Settings::Gui::CloseToTray).toBool()); ui->cbCloseToTray->setChecked(Settings::value(Settings::Gui::CloseToTray).toBool());
ui->cbStopOnDeskSwitch->setChecked(Settings::value(Settings::Core::StopOnDeskSwitch).toBool());
ui->cbElevateDaemon->setChecked(Settings::value(Settings::Daemon::Elevate).toBool()); ui->cbElevateDaemon->setChecked(Settings::value(Settings::Daemon::Elevate).toBool());
ui->cbAutoUpdate->setChecked(Settings::value(Settings::Gui::AutoUpdateCheck).toBool()); ui->cbAutoUpdate->setChecked(Settings::value(Settings::Gui::AutoUpdateCheck).toBool());
@ -288,7 +267,6 @@ void SettingsDialog::updateControls()
if (Settings::isNativeMode()) { if (Settings::isNativeMode()) {
ui->groupService->setEnabled(writable); ui->groupService->setEnabled(writable);
ui->cbElevateDaemon->setEnabled(writable && serviceChecked); ui->cbElevateDaemon->setEnabled(writable && serviceChecked);
ui->cbStopOnDeskSwitch->setEnabled(writable && serviceChecked);
} else if (ui->groupService->isVisibleTo(ui->tabAdvanced)) { } else if (ui->groupService->isVisibleTo(ui->tabAdvanced)) {
ui->groupService->setVisible(false); ui->groupService->setVisible(false);
const int bottomMargin = ui->tabAdvanced->layout()->contentsMargins().bottom() + const int bottomMargin = ui->tabAdvanced->layout()->contentsMargins().bottom() +

View file

@ -560,19 +560,6 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<layout class="QGridLayout" name="_6"> <layout class="QGridLayout" name="_6">
<item row="2" column="0">
<widget class="QCheckBox" name="cbStopOnDeskSwitch">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Run as system only when at the login screen and UAC prompt</string>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QCheckBox" name="cbElevateDaemon"> <widget class="QCheckBox" name="cbElevateDaemon">
<property name="text"> <property name="text">

View file

@ -107,8 +107,7 @@ static void send_mouse_input(DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData)
// //
MSWindowsDesks::MSWindowsDesks( MSWindowsDesks::MSWindowsDesks(
bool isPrimary, bool noHooks, const IScreenSaver *screensaver, IEventQueue *events, IJob *updateKeys, bool isPrimary, bool noHooks, const IScreenSaver *screensaver, IEventQueue *events, IJob *updateKeys
bool stopOnDeskSwitch
) )
: m_isPrimary(isPrimary), : m_isPrimary(isPrimary),
m_noHooks(noHooks), m_noHooks(noHooks),
@ -128,8 +127,7 @@ MSWindowsDesks::MSWindowsDesks(
m_mutex(), m_mutex(),
m_deskReady(&m_mutex, false), m_deskReady(&m_mutex, false),
m_updateKeys(updateKeys), m_updateKeys(updateKeys),
m_events(events), m_events(events)
m_stopOnDeskSwitch(stopOnDeskSwitch)
{ {
m_cursor = createBlankCursor(); m_cursor = createBlankCursor();
@ -757,18 +755,6 @@ void MSWindowsDesks::checkDesk()
desk = index->second; desk = index->second;
} }
// if we are told to shut down on desk switch, and this is not the
// first switch, then shut down.
if (m_stopOnDeskSwitch && m_activeDesk != NULL && name != m_activeDeskName) {
if (name.empty()) {
LOG_DEBUG("shutting down because of desk switch, desktop name unknown");
} else {
LOG_DEBUG("shutting down because of desk switch to: %s", name.c_str());
}
m_events->addEvent(Event(Event::kQuit));
return;
}
// if active desktop changed then tell the old and new desk threads // if active desktop changed then tell the old and new desk threads
// about the change. don't switch desktops when the screensaver is // about the change. don't switch desktops when the screensaver is
// active becaue we'd most likely switch to the screensaver desktop // active becaue we'd most likely switch to the screensaver desktop

View file

@ -54,10 +54,7 @@ public:
updated in a thread attached to the current desk. updated in a thread attached to the current desk.
\p hookLibrary must be a handle to the hook library. \p hookLibrary must be a handle to the hook library.
*/ */
MSWindowsDesks( MSWindowsDesks(bool isPrimary, bool noHooks, const IScreenSaver *screensaver, IEventQueue *events, IJob *updateKeys);
bool isPrimary, bool noHooks, const IScreenSaver *screensaver, IEventQueue *events, IJob *updateKeys,
bool stopOnDeskSwitch
);
~MSWindowsDesks(); ~MSWindowsDesks();
//! @name manipulators //! @name manipulators
@ -278,7 +275,4 @@ private:
bool m_leaveForegroundOption; bool m_leaveForegroundOption;
IEventQueue *m_events; IEventQueue *m_events;
// true if program should stop on desk switch.
bool m_stopOnDeskSwitch;
}; };

View file

@ -82,7 +82,7 @@ HINSTANCE MSWindowsScreen::s_windowInstance = NULL;
MSWindowsScreen *MSWindowsScreen::s_screen = NULL; MSWindowsScreen *MSWindowsScreen::s_screen = NULL;
MSWindowsScreen::MSWindowsScreen( MSWindowsScreen::MSWindowsScreen(
bool isPrimary, bool noHooks, bool stopOnDeskSwitch, IEventQueue *events, bool enableLangSync, bool isPrimary, bool noHooks, IEventQueue *events, bool enableLangSync,
deskflow::ClientScrollDirection scrollDirection deskflow::ClientScrollDirection scrollDirection
) )
: PlatformScreen(events, scrollDirection), : PlatformScreen(events, scrollDirection),
@ -130,7 +130,7 @@ MSWindowsScreen::MSWindowsScreen(
m_screensaver = new MSWindowsScreenSaver(); m_screensaver = new MSWindowsScreenSaver();
m_desks = new MSWindowsDesks( m_desks = new MSWindowsDesks(
m_isPrimary, m_noHooks, m_screensaver, m_events, m_isPrimary, m_noHooks, m_screensaver, m_events,
new TMethodJob<MSWindowsScreen>(this, &MSWindowsScreen::updateKeysCB), stopOnDeskSwitch new TMethodJob<MSWindowsScreen>(this, &MSWindowsScreen::updateKeysCB)
); );
m_keyState = new MSWindowsKeyState( m_keyState = new MSWindowsKeyState(
m_desks, getEventTarget(), m_events, AppUtil::instance().getKeyboardLayoutList(), enableLangSync m_desks, getEventTarget(), m_events, AppUtil::instance().getKeyboardLayoutList(), enableLangSync

View file

@ -33,7 +33,7 @@ class MSWindowsScreen : public PlatformScreen
{ {
public: public:
MSWindowsScreen( MSWindowsScreen(
bool isPrimary, bool noHooks, bool stopOnDeskSwitch, IEventQueue *events, bool enableLangSync = false, bool isPrimary, bool noHooks, IEventQueue *events, bool enableLangSync = false,
deskflow::ClientScrollDirection scrollDirection = deskflow::ClientScrollDirection::SERVER deskflow::ClientScrollDirection scrollDirection = deskflow::ClientScrollDirection::SERVER
); );
virtual ~MSWindowsScreen(); virtual ~MSWindowsScreen();

View file

@ -149,13 +149,9 @@ MSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security, bool elevatedTok
{ {
m_session.updateActiveSession(); m_session.updateActiveSession();
// always elevate if we are at the vista/7 login screen. we could also if (elevatedToken) {
// elevate for the uac dialog (consent.exe) but this would be pointless,
// since deskflow would re-launch as non-elevated after the desk switch,
// and so would be unusable with the new elevated process taking focus.
if (elevatedToken || m_session.isProcessInSession("logonui.exe", nullptr)) {
LOG_DEBUG("getting elevated token, %s", (elevatedToken ? "elevation required" : "at login screen")); LOG_DEBUG("getting elevated token");
HANDLE process; HANDLE process;
if (!m_session.isProcessInSession("winlogon.exe", &process)) { if (!m_session.isProcessInSession("winlogon.exe", &process)) {
@ -290,16 +286,9 @@ void MSWindowsWatchdog::startProcess()
} else { } else {
LOG_DEBUG("starting new process in user session"); LOG_DEBUG("starting new process in user session");
LOG_DEBUG("getting active desktop name");
const auto activeDesktopName = runActiveDesktopUtility();
LOG_DEBUG("active desktop name: %s", activeDesktopName.c_str());
// When we're at a UAC prompt, lock screen, or the login screen, Windows switches to the Winlogon desktop.
const auto isOnSecureDesktop = activeDesktopName == "Winlogon";
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
HANDLE userToken = getUserToken(&sa, isOnSecureDesktop || m_elevateProcess); HANDLE userToken = getUserToken(&sa, m_elevateProcess);
// set UIAccess to fix Windows 8 GUI interaction // set UIAccess to fix Windows 8 GUI interaction
DWORD uiAccess = 1; DWORD uiAccess = 1;
@ -438,53 +427,6 @@ void MSWindowsWatchdog::shutdownExistingProcesses()
CloseHandle(snapshot); CloseHandle(snapshot);
} }
std::string MSWindowsWatchdog::runActiveDesktopUtility()
{
char fileNameBuffer[MAX_PATH];
GetModuleFileName(NULL, fileNameBuffer, MAX_PATH);
std::string fileName(fileNameBuffer);
size_t lastSlash = fileName.find_last_of("\\");
const auto installDir = fileName.substr(0, lastSlash);
const auto coreBinPath = installDir + "\\deskflow-server.exe";
std::string utilityCommand = "\"" + coreBinPath + "\" --active-desktop";
LOG_DEBUG("starting active desktop utility: %s", utilityCommand.c_str());
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
HANDLE userToken = getUserToken(&sa, true);
deskflow::platform::MSWindowsProcess process(utilityCommand);
process.createPipes();
if (!process.startAsUser(userToken, &sa)) {
LOG_ERR("could not start active desktop process");
throw XArch(new XArchEvalWindows());
}
LOG_DEBUG("started active desktop process, pid=%d", process.info().dwProcessId);
if (const auto exitCode = process.waitForExit(); exitCode != kExitSuccess) {
LOG_ERR("active desktop process, exit code: %d", exitCode);
throw XArch("could not get active desktop");
}
LOG_DEBUG("reading active desktop std error");
if (const auto error = process.readStdError(); !error.empty()) {
LOG_WARN("active desktop process, error: %s", error.c_str());
}
LOG_DEBUG("reading active desktop std output");
auto output = process.readStdOutput();
if (output.empty()) {
LOG_ERR("could not get active desktop, no output");
throw XArch("could not get active desktop");
}
output.erase(output.find_last_not_of("\r\n") + 1);
return output;
}
MSWindowsWatchdog::ProcessState MSWindowsWatchdog::handleStartError(const std::string_view &message) MSWindowsWatchdog::ProcessState MSWindowsWatchdog::handleStartError(const std::string_view &message)
{ {
const auto kStartDelaySeconds = 1; const auto kStartDelaySeconds = 1;

View file

@ -111,16 +111,6 @@ private:
*/ */
void initSasFunc(); void initSasFunc();
/**
* @brief Re-run the process to get the active desktop name.
*
* It is necessary to run a utility process because the daemon runs in session 0, which does not
* have access to the active desktop, and so cannot query it's name.
*
* @return std::string The name of the active desktop.
*/
std::string runActiveDesktopUtility();
/** /**
* @brief Allows the SendSAS function to be called from other processes. * @brief Allows the SendSAS function to be called from other processes.
* *