Vencord / Vesktop

Vesktop is a custom Discord App aiming to give you better performance and improve linux support
GNU General Public License v3.0
4.1k stars 184 forks source link

Do not auto idle if user is still actively using their computer (e.g. mouse / keyboard activity) #396

Open UlyssesZh opened 8 months ago

UlyssesZh commented 8 months ago

Describe the bug

Discord web goes to auto idle when the web page is unfocused for some time. Discord desktop client goes to auto idle when the user input is inactive for some time regardless of whether the client window is focused. The latter is much more sensible than the former. While I see there are limitations for a web page, I think this should be considered a bug because Vesktop is not behaving like what one would expect a desktop client to do.

To Reproduce

Expected behavior

Screenshots

Desktop (please complete the following information):

Command line output

Additional context

NickelWW commented 7 months ago

I noticed this behavior as well, and I agree

Desktop:

ghost commented 7 months ago

I'm experiencing this issue as well. It's likely a limitation of Electron and it likely wouldn't be worth it to try and fix. I think a more sensible solution would be to have the option to disable idle functionality all together as suggested in #451.

NickelWW commented 7 months ago

I'm experiencing this issue as well. It's likely a limitation of Electron and it likely wouldn't be worth it to try and fix. I think a more sensible solution would be to have the option to disable idle functionality all together as suggested in #451.

I don't think so, because stock discord desktop is also an electron app and it doesn't have this issue...

ghost commented 7 months ago

I may have phrased that wrong. Discord is Electron + a bunch of proprietary stuff, such as their rich status API and screen sharing (which is why it didn't work with Wayland and why it doesn't have sound on Linux in the official client). I would assume (and I am assuming here) that this would be another custom component that would instead have to be implemented manually.

UlyssesZh commented 5 months ago

It seems that Vendicated/Vencord#2342 can partially solve this problem.

Vendicated commented 4 months ago

so just for clarification since I myself got confused, this issue is about vesktop still idling even if the user is actively using their mouse/keyboard/...

vesktop could definitely fix that and copy the discord desktop behaviour of only idling if there's no input. but likely only on X11/XWayland, not Wayland. globally hooking mouse & keyboard input is a bit invasive, so this should probably be toggleable

UlyssesZh commented 4 months ago

Yes, this is what I meant.

It's good to hear that this is possible.

Vendicated commented 4 months ago

Discord Desktop logic (cleaned up & simplified, search for "IdleStore to find this in code):

function isSystemIdle() {
  return suspended || locked || (isAndroid() && idkIrrelevantWhoCares);
}

function checkIdleNative() {
    let checkIdleTime = t => {
        idleSince = Math.max(Date.now() - t, idleSince),
        checkIdleAFK(),
        setTimeout(checkIdleNative, 10 * d.Z.Millis.SECOND)
    }
    DiscordNative.remotePowerMonitor.getSystemIdleTimeMs()
        .then(checkIdleTime);
}

checkIdleNative();

function handleEvent() {
    // [...]
    checkIdleOrAfk();
}

DiscordNative.remotePowerMonitor.on("resume", ()=>{
    suspended = false,
    handleEvent()
}
),
DiscordNative.remotePowerMonitor.on("suspend", ()=>{
    suspended = true,
    handleEvent()
    disconnectFromVoiceChannel();
}
),
DiscordNative.remotePowerMonitor.on("lock-screen", ()=>{
    locked = true,
    handleEvent()
}
),
DiscordNative.remotePowerMonitor.on("unlock-screen", ()=>{
    locked = false,
    handleEvent()
}

we will have to port this logic. we will have to patch the isSystemIdle function to replace locked and suspended with our own variables. we can call handleEvent() by dispatching a OVERLAY_SET_NOT_IDLE flux event

their powerMonitor native events just come from electron:

electron.powerMonitor.on('resume', () => {
  sendToAllWindows(POWER_MONITOR_RESUME);
});
electron.powerMonitor.on('suspend', () => {
  sendToAllWindows(POWER_MONITOR_SUSPEND);
});
electron.powerMonitor.on('lock-screen', () => {
  sendToAllWindows(POWER_MONITOR_LOCK_SCREEN);
});
electron.powerMonitor.on('unlock-screen', () => {
  sendToAllWindows(POWER_MONITOR_UNLOCK_SCREEN);
});
electron.ipcMain.handle(POWER_MONITOR_GET_SYSTEM_IDLE_TIME, async () => {
  return electron.powerMonitor.getSystemIdleTime() * 1000;
});