Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/mumble/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ set(MUMBLE_SOURCES
"SettingsKeys.h"
"Settings.cpp"
"Settings.h"
"SleepInhibitor.cpp"
"SleepInhibitor.h"
"SharedMemory.cpp"
"SharedMemory.h"
"SocketRPC.cpp"
Expand Down
2 changes: 2 additions & 0 deletions src/mumble/LookConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ void LookConfig::load(const Settings &r) {

loadCheckBox(qcbEnableDeveloperMenu, r.bEnableDeveloperMenu);
loadCheckBox(qcbLockLayout, (r.wlWindowLayout == Settings::LayoutCustom) && r.bLockLayout);
loadCheckBox(qcbInhibitSleep, r.bInhibitSleep);
loadCheckBox(qcbHideTray, r.bHideInTray);
loadCheckBox(qcbStateInTray, r.bStateInTray);
loadCheckBox(qcbShowUserCount, r.bShowUserCount);
Expand Down Expand Up @@ -309,6 +310,7 @@ void LookConfig::save() const {
s.quitBehavior = static_cast< QuitBehavior >(qcbQuitBehavior->currentIndex());
s.bEnableDeveloperMenu = qcbEnableDeveloperMenu->isChecked();
s.bLockLayout = qcbLockLayout->isChecked();
s.bInhibitSleep = qcbInhibitSleep->isChecked();
s.bHideInTray = qcbHideTray->isChecked();
s.bStateInTray = qcbStateInTray->isChecked();
s.bShowUserCount = qcbShowUserCount->isChecked();
Expand Down
10 changes: 10 additions & 0 deletions src/mumble/LookConfig.ui
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="qcbInhibitSleep">
<property name="toolTip">
<string>Prevents the computer from sleeping while connected to a server</string>
</property>
<property name="text">
<string>Inhibit system sleep while connected</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down
13 changes: 13 additions & 0 deletions src/mumble/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "ServerHandler.h"
#include "ServerInformation.h"
#include "Settings.h"
#include "SleepInhibitor.h"
#include "SvgIcon.h"
#include "TalkingUI.h"
#include "TextMessage.h"
Expand Down Expand Up @@ -208,6 +209,8 @@ MainWindow::MainWindow(QWidget *p)
QObject::connect(this, &MainWindow::channelStateChanged, this, &MainWindow::on_channelStateChanged);

QAccessible::installFactory(AccessibleSlider::semanticSliderFactory);

m_sleepInhibitor = new SleepInhibitor(this);
}

// Loading a state that was stored by a different version of Qt can lead to a crash.
Expand Down Expand Up @@ -3511,6 +3514,10 @@ void MainWindow::serverConnected() {
MUSuppressAppNap(true);
#endif

if (Global::get().s.bInhibitSleep) {
m_sleepInhibitor->setInhibit(true);
}

Global::get().l->clearIgnore();
Global::get().l->setIgnore(Log::UserJoin);
Global::get().l->setIgnore(Log::OtherSelfMute);
Expand Down Expand Up @@ -3579,6 +3586,8 @@ void MainWindow::serverDisconnected(QAbstractSocket::SocketError err, QString re
MUSuppressAppNap(false);
#endif

m_sleepInhibitor->setInhibit(false);

QString uname, pw, host;
unsigned short port;
Global::get().sh->getConnectionInfo(host, port, uname, pw);
Expand Down Expand Up @@ -4222,6 +4231,10 @@ void MainWindow::openConfigDialog() {
close();
}
}

if (Global::get().uiSession != 0) {
m_sleepInhibitor->setInhibit(Global::get().s.bInhibitSleep);
}
}

Global::get().inConfigUI = false;
Expand Down
3 changes: 3 additions & 0 deletions src/mumble/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class UserInformation;
class VoiceRecorderDialog;
class PositionalAudioViewer;
class PTTButtonWidget;
class SleepInhibitor;

namespace Search {
class SearchDialog;
Expand Down Expand Up @@ -206,6 +207,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindow {
std::stack< unsigned int > m_previousChannels;
std::optional< unsigned int > m_movedBackFromChannel;

SleepInhibitor *m_sleepInhibitor;

static constexpr int stateVersion();

void createActions();
Expand Down
1 change: 1 addition & 0 deletions src/mumble/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ struct Settings {
bool bLockLayout = false;
bool bHideInTray = false;
bool bStateInTray = true;
bool bInhibitSleep = false;
bool bUsage = true;
bool bShowUserCount = false;
bool bShowVolumeAdjustments = true;
Expand Down
1 change: 1 addition & 0 deletions src/mumble/SettingsKeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ const SettingsKey OVERLAY_HEADER_STATE = { "overlay_header_state
const SettingsKey SERVER_FILTER_MODE_KEY = { "server_filter_mode" };
const SettingsKey HIDE_IN_TRAY_KEY = { "hide_in_tray" };
const SettingsKey DISPLAY_TALKING_STATE_IN_TRAY_KEY = { "display_talking_state_in_tray" };
const SettingsKey INHIBIT_SLEEP_KEY = { "inhibit_sleep" };
const SettingsKey SEND_USAGE_STATISTICS_KEY = { "send_usage_statistics" };
const SettingsKey DISPLAY_USER_COUNT_KEY = { "display_user_count" };
const SettingsKey DISPLAY_VOLUME_ADJUSTMENTS_KEY = { "display_volume_adjustments" };
Expand Down
1 change: 1 addition & 0 deletions src/mumble/SettingsMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
PROCESS(ui, USER_DRAG_MODE_KEY, ceUserDrag) \
PROCESS(ui, ALWAYS_ON_TOP_KEY, aotbAlwaysOnTop) \
PROCESS(ui, QUIT_BEHAVIOR_KEY, quitBehavior) \
PROCESS(ui, INHIBIT_SLEEP_KEY, bInhibitSleep) \
PROCESS(ui, SHOW_DEVELOPER_MENU_KEY, bEnableDeveloperMenu) \
PROCESS(ui, LOCK_LAYOUT_KEY, bLockLayout) \
PROCESS(ui, MINIMAL_VIEW_KEY, bMinimalView) \
Expand Down
95 changes: 95 additions & 0 deletions src/mumble/SleepInhibitor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "SleepInhibitor.h"
#include "Global.h"

#if defined(Q_OS_WIN)
# include <windows.h>
#elif defined(Q_OS_MAC)
# include <IOKit/pwr_mgt/IOPMLib.h>
#elif defined(USE_DBUS)
# include <QtDBus/QtDBus>
#endif

SleepInhibitor::SleepInhibitor(QObject *parent) : QObject(parent) {
}

SleepInhibitor::~SleepInhibitor() {
setInhibit(false);
}

void SleepInhibitor::setInhibit(bool inhibit) {
if (inhibit == m_inhibited) {
return;
}

if (inhibit) {
platformInhibit();
} else {
platformDeinhibit();
}

m_inhibited = inhibit;
}

void SleepInhibitor::platformInhibit() {
#if defined(Q_OS_WIN)
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
#elif defined(Q_OS_MAC)
CFStringRef reasonForActivity = CFStringCreateWithCString(kCFAllocatorDefault, "Mumble is in a call", kCFStringEncodingUTF8);
IOReturn success = IOPMAssertionCreateWithDescription(kIOPMAssertionTypeNoDisplaySleep,
reasonForActivity,
NULL, NULL, NULL, 0, NULL,
&m_assertionID);
CFRelease(reasonForActivity);
if (success != kIOReturnSuccess) {
qWarning("SleepInhibitor: Failed to create IOPMAssertion");
m_assertionID = 0;
}
#elif defined(USE_DBUS)
QDBusInterface screensaver("org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver", QDBusConnection::sessionBus());
if (screensaver.isValid()) {
QDBusReply<uint32_t> reply = screensaver.call("Inhibit", "Mumble", "In a call");
if (reply.isValid()) {
m_cookie = reply.value();
} else {
qWarning() << "SleepInhibitor: ScreenSaver Inhibit call failed:" << reply.error().message();
}
}

QDBusInterface logind("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
if (logind.isValid()) {
QDBusReply<QDBusUnixFileDescriptor> reply = logind.call("Inhibit", "sleep:idle", "Mumble", "In a call", "block");
if (reply.isValid()) {
m_logindFD = reply.value();
} else {
qWarning() << "SleepInhibitor: Logind Inhibit call failed:" << reply.error().message();
}
}
#endif
}

void SleepInhibitor::platformDeinhibit() {
#if defined(Q_OS_WIN)
SetThreadExecutionState(ES_CONTINUOUS);
#elif defined(Q_OS_MAC)
if (m_assertionID != 0) {
IOPMAssertionRelease(m_assertionID);
m_assertionID = 0;
}
#elif defined(USE_DBUS)
if (m_cookie != 0) {
QDBusInterface screensaver("org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver", QDBusConnection::sessionBus());
if (screensaver.isValid()) {
screensaver.call("UnInhibit", m_cookie);
}
m_cookie = 0;
}
if (m_logindFD.isValid()) {
m_logindFD = QDBusUnixFileDescriptor();
}
#endif
}
39 changes: 39 additions & 0 deletions src/mumble/SleepInhibitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#ifndef MUMBLE_MUMBLE_SLEEPINHIBITOR_H_
#define MUMBLE_MUMBLE_SLEEPINHIBITOR_H_

#include <QtCore/QObject>
#if defined(USE_DBUS)
# include <QtDBus/QDBusUnixFileDescriptor>
#endif

class SleepInhibitor : public QObject {
Q_OBJECT
Q_DISABLE_COPY(SleepInhibitor)

public:
explicit SleepInhibitor(QObject *parent = nullptr);
~SleepInhibitor() override;

void setInhibit(bool inhibit);

private:
bool m_inhibited = false;
#if defined(Q_OS_WIN)
// No extra state needed for Windows (ES_CONTINUOUS)
#elif defined(Q_OS_MAC)
uint32_t m_assertionID = 0;
#elif defined(USE_DBUS)
uint32_t m_cookie = 0;
QDBusUnixFileDescriptor m_logindFD;
#endif

void platformInhibit();
void platformDeinhibit();
};

#endif
Loading