johndbritton / teleport

Virtual KVM for macOS
GNU General Public License v2.0
790 stars 132 forks source link

Prevent machines from sleeping #58

Open johndbritton opened 3 years ago

johndbritton commented 3 years ago

Feature request

A detailed description of the proposed feature

It would be helpful if the Teleport could keep my machines awake. When my server connects to a client and controls it remotely, it's not uncommon for the server to sleep the display. Likewise when I'm using the server it's common for the client to sleep the display.

The motivation for the feature

When Teleport is active, I want all of my connected machines to stay awake if I am active on any of the connected machines. Alternatively, the ability to wake a machine when the mouse would move to it would also be good but might be harder to implement.

How the feature would be relevant to at least 90% of Teleport users

Anyone who uses one computer for a prolonged period of time will have this issue.

What alternatives to the feature have been considered

Use an external application like Amphetamine to keep the machines from sleeping. This works, but it keeps the machines awake indefinitely and it would be more convenient if they went to sleep on a normal schedule when not in use.

reaperhulk commented 3 years ago

Does teleport keep a persistent connection to the machine? I looked at this a bit today (while building #65) and it didn't seem like there was a persistent control channel that could be used to send wakeup events. If not then maybe something like the below would work?

    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(screensDidWake:) name:NSWorkspaceScreensDidWakeNotification object:nil];

- (void)screensDidWake:(NSNotification*)notification
{
    NSLog(@"waking screens");
    NSArray *hosts = [[TPHostsManager defaultManager] hostsWithState:TPHostOnlineState];
    for (TPRemoteHost *host in hosts) {
        BOOL isLocalHost = [host isEqual:[TPLocalHost localHost]];
        if (!isLocalHost) {
            //init a connection and send an event that triggers wakeUpScreen on the target machine
        }
    }
}

This would only wake all the screens at the same time though, so you'd also want something on a timer to keep sending those wakeup events to the clients every n seconds. You could also then implement an observer for sleeping:

    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(screensDidSleep:) name:NSWorkspaceScreensDidSleepNotification object:nil];

- (void)screensDidSleep:(NSNotification*)notification
{
    NSLog(@"sleeping screens");
        // disable the wake loop and then send sleep commands to every client
}

A sleepScreen like this would work as a new method on TPLocalHost:

- (void)sleepScreen {
    io_registry_entry_t entry = IORegistryEntryFromPath(kIOMasterPortDefault,
                                                        "IOService:/IOResources/IODisplayWrangler");
    if (entry != MACH_PORT_NULL) {
        IORegistryEntrySetCFProperty(entry, CFSTR("IORequestIdle"), kCFBooleanTrue);
        IOObjectRelease(entry);
    }
}
johndbritton commented 3 years ago

Some of this issue was addressed in https://github.com/johndbritton/teleport/pull/66, but I think there's still more to do before we call this resolved.

johndbritton commented 3 years ago

From https://github.com/johndbritton/teleport/pull/66

The workaround for the sleep issue right now would be to set the display sleep interval to 1 minute on the controlled machine. Since a wake ping is sent every ~50s it will never sleep, but once the primary display is put to sleep it will sleep within at most 60s.

I don't think we should require the user to set specific sleep settings in preferences because it's possible that the machine is portable and it's not always paired.

In my case, I control a MacBook Air when I'm at my desk, but that machine also goes with me when I travel. I don't want to change the way I have it configured but I do want it to stay awake when it's being controlled with Teleport.

As of v1.3.1 when my air is controlled the display does not sleep, but the computer does end up on a lock screen if I don't mouse over to it from time to time. I'd like for it to stay on, awake, and unlocked unless I become inactive on the controlling device. With v1.3.1 even though the machine locks, I am still able to wake it (and enter a password) from the controlling machine which is much better than the old behavior.

reaperhulk commented 3 years ago

Interesting -- on my setup I don't need to mouseover to keep the screen from locking. If you're on Big Sur 11.1 it would seem there are differences in behavior here that bear closer investigation...

johndbritton commented 3 years ago

I'm using Catalina on the controlling machine and Big Sur on the controlled machine.

johndbritton commented 3 years ago

it would seem there are differences in behavior here that bear closer investigation

It could also stem from differing machine settings. Here's what my Security & Privacy General settings say on the controlled machine:

Screen Shot 2020-12-25 at 3 21 39 PM
johndbritton commented 3 years ago

and Desktop & Screensaver preferences:

Screen Shot 2020-12-25 at 3 22 57 PM

Looks like this could be caused by my screen saver being enabled