VLCKit-based app prevents screensaver - macos

I've recently built a simple Swift macOS app based upon VLCKit; its purpose is mainly to play IP camera streams via RTSP in a window that stays always visible on screen (i.e. to monitor a gate).
Given the purpose of the app, I keep the streaming playing all the time, except when the user minimizes it in the Dock (meaning that I only call mediaPlayer?.stop in viewDidDisappear).
The app works very well, but I've recently discovered that, unless it is minimized (and, as a consequence, the playback is already stopped), something prevents the screensaver from running.
I've tried subscribing to all NSNotificationCenter com.apple.screensaver.* notifications, and I've realized that when the playback is running, none of them is fired; if I minimize the app and stop the playback, everything behaves normally (screensaver starts after the regular delay, all the com.apple.screensaver notifications are properly detected).
I've also tried running pmset -g to check if my app was listed as preventing sleep, but it's not.
My impression, but I might be wrong, is that my instance of VLCMediaPlayer by default prevents the screensaver launch.
I know that in the VLC Mac app the screensaver can be manually prevented via an advanced setting, but I can't seem to be able to find a parameter to set in my code to tell VLCKit to stop blocking the screensaver.
To your knowledge, by default VLCKit prevents the screensaver from running? Is there a way to alter that behavior?
Please let me know if you need any further detail... and thanks in advance!

In VLC, there are options called "--disable-screensaver" and "--no-disable-screensaver". By default, "--disable-screensaver" is used.
If you want to enable screensaver just do this:
NSArray *options = #[#"--no-disable-screensaver"];
_mediaPlayer1 = [[VLCMediaPlayer alloc] initWithOptions:options];
What else options available in your VLC lib? pass option "--help" to your VLC and it will list all available options.
What is the full list of options? https://wiki.videolan.org/VLC_command-line_help/

It turned out VLCKit does actually prevent the screensaver from running by default, and that it doesn't use libvlc to do so, so the libvlc option "--no-disable-screensaver" I was at one point trying to pass was not respected.
The solution was to comment out a UpdateSystemActivity() function call on line 1409 of VLCMediaPlayer.m, as suggested to me here.

Related

PrefPane in 10.15 will not reopen external windows

My Pref Pane opens a window for each display similar to how the Displays PrefPane works. When I first launch, the OS calls my mainViewDidLoad where I open external windows using initWithWindowNibName. This works fine.
Then in willUnselect, I call [window orderOut:self]; for each external window and they correctly hide. This will happen for example if the user switches from my PrefPane to the Sound or Network PrefPane.
When they come back to my PrefPane, I get willSelect and call:
[window orderWindow:NSWindowAbove relativeTo:0];
This call no longer works (it works in all versions of 10.14.6 and earlier and may work in early versions of 10.15, but it definitely broken in 10.15.6).
I have tried using other methods to hide/show the windows including [window setIsVisible:] but nothing works to restore the window.
I think it might be related to something this blog discusses:
https://www.noodlesoft.com/blog/2019/08/28/preference-panes-and-catalina/
Has anyone seen this or know a fix for it?
After working with Apple DTS, this is expected behavior in that PrefPanes now run in a separate process and that process does not expect panes to open additional windows.
It is still possible to open/close windows within didSelect, but that is more of a side-effect and may not work in the long run. We have decided to pull our software out of System Preferences and into a regular application to ensure long term compatibility.

Unexpected -psn_0_65552 command line argument after mac reboot

When I reboot my mac, if an application that I'm developing was running during reboot, macos starts that application right after restart with "-psn_0_65552" argument. I assume that this is related to "Reopen windows when logging back in" checkbox enabled on restart prompt. I tried to find any documentation about this argument, but failed. So, my questions:
Is this behavior documented somewhere?
Any other weird command-line arguments my application should be able to handle?
Can I avoid my application reopening after mac restart?
Nobody else has offered you anything yet so maybe this will help:
Is this behavior documented somewhere?
The state preservation and restoration mechanism is at least partially documented through the methods you can call to participate in it, e.g. NSWindow's restorable & encodeRestorableStateWithCoder:, NSWindowDelegate's window:willEncodeRestorableState:, NSApplication's restoreWindowWithIdentifier:state:completionHandler: etc. However how the various AppKit classes preserve and restore all the information is not publicly documented (there is a statement to that effect in the docs somewhere).
Any other weird command-line arguments my application should be able to handle?
Anybody's guess.
Can I avoid my application reopening after mac restart?
Maybe. Some apps don't restart on relaunch, whether their authors control this or its happenstance I've no idea.
Here's a suggestion: write yourself a very basic GUI app which just saves the arguments and environment (you can use NSProcessInfo to get them all) at launch time to user defaults. Lunch your app from Xcode, Finder and Terminal. Reboot while its open. Look at the user defaults (look in its sandbox and open the .plist in Xcode). Notice anything? Want to rely on it? Your call.
Can you think of others way to track your app launches and user-initiated quits? Maybe setting and removing a flag in user defaults? Have fun!
HTH

Is it normal for Apple to reject an app for using UIApplication to disable screen lock?

I just had an app rejected because I have a user changeable setting which allows the user to disable screen lock via
[UIApplication sharedApplication].idleTimerDisabled = YES;
Apple says I used an undocumented API but it IS indeed documented here: https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplication_Class/index.html#//apple_ref/occ/instp/UIApplication/idleTimerDisabled
My app graphs the barometric pressure and if you want the graph to run longer than a minute or two, it is important to disable screen lock. The default behavior is screen locking as usual, but there's an option in the settings to disable screen lock and this seems to be what Apple took issue with. I've had academic users request this feature, and I have used it in other apps successfully, however this time Apple rejected my app for using it. Is this normal? Is disabling screen lock via UIApplication really now allowed?
I am not sure but I think the issue is that note under the important heading with the documentation you shared;
"You should set this property only if necessary and should be sure to
reset it to NO when the need no longer exists. Most apps should let
the system turn off the screen when the idle timer elapses ..."
You should write into resolution center and confirm this;
We use that capability to prevent idle sleep when we are updating the firmware on a BlueTooth device. Immediately upon completing the update, we restore idle timeout. Apple never said a thing to us about it.
However, in your case, there is no technical reason to disable the idle timer. Your data collection is not going to fail because the system went idle. There is no adverse or unusual customer experience going to be had. That is probably what Apple took exception to.
Three possible paths exist:
1) Gather your data at intervals in the background while the system is idle and update the graph when the app again comes to the front.
2) Add messaging to your app to tell the user that if they want continuous display, they will need to change the idle timeout period in system settings. (With caveats about impact on battery charge duration.)
3) State your case to Apple.
I would go for both 1 & 2

Starting my app when USB device connected

I need to starting my app when our USB device connected.
My first attempt at this is a background application that pays attention to when USB devices are plugged in. When it notices our device connected, it calls ShellExecute( ) and starts our application.
This works nicely except in Windows 8. Supposing we're on the "Start" screen in Windows 8. In that situation, the application starts in the background and the start screen remains in front.
I think this is a "focus" problem since what I'm actually hoping to do is "steal focus" from the Start screen.
http://blogs.msdn.com/b/oldnewthing/archive/2009/02/20/9435239.aspx
Since my background application doesn't have focus (the Start screen has focus; besides, my application doesn't have a UI), it can't give focus away to my foreground application.
Let me say that in general, I hate focus stealing. Starting the app the user wants to use is a great help to our users.
How can I fix this problem? Maybe the answer is to programmatically ask the start screen to start my app but I don't see a way to do that:
http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/9ed23f32-0708-48a8-9ff7-5fce6dbe123f/windows-8-start-screen-api
Maybe I'm approaching this in the wrong way. Suggestions?
You're going about this the wrong way. Although you can write a program to constantly monitor the USB ports to detect when something is connected, there's no need. The OS is already doing that anyway.
Register an Autoplay handler for your device type and class. This is distinct from the old AutoRun feature, which would automatically execute programs found on an inserted file system.
You can begin with an overview of the feature from the November 2001 issue of MSDN Magazine.
Your handler will be a COM DLL. You can register the DLL as a handler, and register the handler with events you want to handle. You can either perform everything in the DLL, or you can put the bulk of the functionality in your application and just use the DLL as a proxy between the OS and your program.

Strange behavior in user idle detection in Adobe Air on Mac

I've got an Adobe AIR application written in pure AS3 that has some functionality that happens when the user is idle and then returns to the normal state when the user returns. I'm detecting this activity with the following code:
NativeApplication.nativeApplication.idleThreshold = 180;
NativeApplication.nativeApplication.addEventListener(Event.USER_IDLE, onUserIdle);
NativeApplication.nativeApplication.addEventListener(Event.USER_PRESENT, onUserPresent);
The onUserIdle method is called after 3 minutes as it should be, but then the onUserPresent event is fired almost immediately afterwards. I'm talking milliseconds later. This happens without any user input whatsoever. The bizarre thing is that this does not occur on Windows - only on OSX. And it happens on all flavors of OSX going back to 10.6.3.
Adobe's documentation is incredibly vague on how those events are determined, so I'm not sure if there is something I can do at the system level to fix the problem. Does anyone have any experience with this issue, and if not, any other suggestions on how I can detect user idleness even when the app does not have focus?
Just to preempt the suggestion, I cannot use mouse/keyboard listeners to simulate the same behavior because they do not work if the application loses focus, whereas the NativeApplication events still fire. I've also used NativeProcess to get the output of ioreg to get the hardware idle time as reported by the system, but it does not appear to be affected by the mouse.
I really appreciate any assistance.
Edit: I just discovered that this does not occur when the application is run in an Administrator account on OSX. It only happens in a User account, which only serves to confuse me more.
I figured out what the issue is. When the USER_IDLE event is fired in a user account, we did several things - one of which was forcibly kill the Dock in order to make sure it was hidden from the screen. For whatever reason, this resets the internally available idleThreshold count. This was not only happening in AIR - it was also happening when monitored through Terminal and it appears there is absolutely nothing that can be done to stop it. The solution was to stop killing the dock. Everything magically worked after that.

Resources