Add auto-away feature for Linux X11

This commit is contained in:
miruka 2020-07-11 00:51:53 -04:00
parent 10f47f71ac
commit 3c620f6fd1
10 changed files with 107 additions and 15 deletions

View File

@ -1,6 +1,9 @@
# TODO
- account can't see another's status message once it goes offline
- mark accounts as offline when closing mirage
- document new x11 dependnecy (auto-idle)
- auto-idle for Windows and OSX
- open context menus centered on touch screens
- retrieve last seen time for offline members on hover/in profile
- auto-away after a configurable idle time
- status based on process detection

View File

@ -16,6 +16,10 @@ HEADERS += src/utils.h src/clipboard.h submodules/hsluv-c/src/hsluv.h
SOURCES += src/main.cpp submodules/hsluv-c/src/hsluv.c
TARGET = mirage
unix:!macx {
LIBS += -lX11 -lXss
}
# Custom CONFIG options

View File

@ -1290,7 +1290,10 @@ class MatrixClient(nio.AsyncClient):
async def set_presence(
self, presence: str, status_msg: Optional[str] = None,
self,
presence: str,
status_msg: Optional[str] = None,
save: bool = True,
) -> None:
"""Set presence state for this account."""
@ -1326,9 +1329,13 @@ class MatrixClient(nio.AsyncClient):
if not account.presence_support:
account.presence = Presence.State(presence)
if save:
account.save_presence = True
await self.backend.saved_accounts.update(
self.user_id, presence=presence,
)
else:
account.save_presence = False
await super().set_presence(
"offline" if presence == "invisible" else presence,

View File

@ -143,6 +143,7 @@ class Account(ModelItem):
# For some reason, Account cannot inherit Presence, because QML keeps
# complaining type error on unknown file
presence_support: bool = False
save_presence: bool = True
presence: Presence.State = Presence.State.offline
currently_active: bool = False
last_active_at: datetime = ZERO_DATE

View File

@ -632,6 +632,7 @@ class NioCallbacks:
account.presence_support = True
# Save the presence for the next resume
if account.save_presence:
await self.client.backend.saved_accounts.update(
user_id = ev.user_id,
presence = presence.presence.value if (

View File

@ -248,6 +248,7 @@ class UISettings(JSONDataFile):
"alertOnMentionForMsec": -1,
"alertOnMessageForMsec": 0,
"alwaysCenterRoomHeader": False,
"beUnavailableAfterSecondsIdle": 60 * 10,
"compactMode": False,
"clearRoomFilterOnEnter": True,
"clearRoomFilterOnEscape": True,

View File

@ -11,8 +11,7 @@
#include <QObject>
class Clipboard : public QObject
{
class Clipboard : public QObject {
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QString selection READ selection WRITE setSelection

45
src/gui/IdleManager.qml Normal file
View File

@ -0,0 +1,45 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import CppUtils 0.1
import "."
Timer {
readonly property ListModel accounts: ModelStore.get("accounts")
readonly property var accountsSet: new Set()
function setPresence(userId, presence) {
py.callClientCoro(userId, "set_presence", [presence, undefined, false])
}
interval: 1000
running: window.settings.beUnavailableAfterSecondsIdle > 0
repeat: true
onTriggered: {
let changes = false
const beUnavailable =
CppUtils.idleMilliseconds() / 1000 >=
window.settings.beUnavailableAfterSecondsIdle
for (let i = 0; i < accounts.count; i++) {
const account = accounts.get(i)
if (beUnavailable && account.presence === "online") {
setPresence(account.id, "unavailable")
accountsSet.add(account.id)
changes = true
} else if (! beUnavailable && accountsSet.has(account.id)) {
setPresence(account.id, "online")
accountsSet.delete(account.id)
changes = true
}
}
if (changes) accountsSetChanged()
}
}

View File

@ -33,6 +33,7 @@ Item {
readonly property alias pageLoader: pageLoader
readonly property alias pressAnimation: pressAnimation
readonly property alias fontMetrics: fontMetrics
readonly property alias idleManager: idleManager
function reloadSettings() {
@ -96,6 +97,10 @@ Item {
visible: false
}
IdleManager {
id: idleManager
}
LinearGradient {
id: mainUIGradient
visible: ! image.visible

View File

@ -11,11 +11,14 @@
#include <QObject>
#include <QUuid>
#ifdef Q_OS_UNIX
#include <X11/extensions/scrnsaver.h>
#endif
#include "../submodules/hsluv-c/src/hsluv.h"
class Utils : public QObject {
Q_OBJECT
public:
@ -44,6 +47,29 @@ public slots:
);
}
int idleMilliseconds() const {
#ifdef Q_OS_DARWIN
return -1;
#elif defined(Q_OS_UNIX)
Display *display = XOpenDisplay(NULL);
if (! display) return -1;
XScreenSaverInfo *info = XScreenSaverAllocInfo();
XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
const int idle = info->idle;
XCloseDisplay(display);
return idle;
#elif defined(Q_OS_WINDOWS)
return -1;
#else
return -1;
#endif
}
private:
QLocale appLocale;
};