Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
11 changes: 11 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 Expand Up @@ -1288,6 +1298,7 @@
<tabstop>qcbQuitBehavior</tabstop>
<tabstop>qcbEnableDeveloperMenu</tabstop>
<tabstop>qcbLockLayout</tabstop>
<tabstop>qcbInhibitSleep</tabstop>
<tabstop>qcbHideTray</tabstop>
<tabstop>qcbStateInTray</tabstop>
<tabstop>qcbSearchUserAction</tabstop>
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
94 changes: 94 additions & 0 deletions src/mumble/SleepInhibitor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// 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"

#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
}
41 changes: 41 additions & 0 deletions src/mumble/SleepInhibitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// 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 <cstdint>

#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