In-app screensaver?

I’m sure I’m missing something obvious here, but I can’t seem to find a way to prevent the screensaver from showing without interaction from the user. Do the roVideoScreen and roSlideShow have built in “keep-alives” or am I missing something in the SDK apps that are preventing the screensaver from displaying? I’m currently using an roImageCanvas to display a custom screen layout for my application, and would like to have my own in-app screensaver, but can’t figure out how to prevent the built-in screensaver from displaying.

Thanks in advance…
TheEndless

So.. it seems the Pandora channel does exactly what I’m trying to do, so it should be possible. If I recreate my screen (not redraw) on a regular basis, I’ve found that it will cancel the screensaver if it’s popped up, but that’s a little messy. I can’t find anything in the documentation or SDK apps that addresses this.

Interestingly, the Pandora channel also seems to respect the screensaver wait time that’s configured on the box, but I don’t see where that configuration information is available through the SDK, either.

Any help would be appreciated. Thanks!
TheEndless

Channel specific screen savers are implemented the same way as ordinary screen savers. The only difference is a single line in the manifest file. Check out pages 7 and 10 of the component reference as well as the Clock sample application to see how it all works.

“nowhereman” wrote:
Channel specific screen savers are implemented the same way as ordinary screen savers. The only difference is a single line in the manifest file. Check out pages 7 and 10 of the component reference as well as the Clock sample application to see how it all works.
I had actually read that, but there’s no clear indication that it applies to in-app screensavers. In fact, the “screensaver_private” setting description is the only thing that even suggests that the screensaver can be app specific. I guess I should read less literally :wink:

Thanks for the pointer!

TheEndless

Ok. I’m clearly missing something obvious here. I’ve added the two screensaver lines to my manifest, and I’ve implemented the RunScreenSaver() entry point, but the default screensaver still loads after the configured idle wait time. The Roku clock SDK app is a sample of a standalone screensaver, and does not give me any information on how to make it app specific.

I’m sorry if I’m being dense here, but I’m really struggling to figure this out. What am I missing?

Thanks…
TheEndless

Can I get anymore feedback on this? I’m rapidly approaching a somewhat stable release of my application, and I’d really like to have a more elegant screensaver solution than I’ve currently implemented.

Thanks again!
TheEndless

Any chance I could at least get a “that’s not possible” or a “you’re an idiot” so I know if it’s worth me continuing to beat my head against the wall trying to figure this out? Patrick? nowhereman? Anyone? Thanks…

Private screen savers that only activate when a certain channel is running are very possible. And it sounds like you’re on the right track with the manifest and entry point. Without seeing your code or knowing in more detail what you’re trying to accomplish, there isn’t much more advice I can offer.

“nowhereman” wrote:
Private screen savers that only activate when a certain channel is running are very possible. And it sounds like you’re on the right track with the manifest and entry point. Without seeing your code or knowing in more detail what you’re trying to accomplish, there isn’t much more advice I can offer.
I’m basically asking for an example of how to do it. My code is very straightforward in this respect. I have a “RunUserInterface()” method that launches the UI, with the standard “waits” on each “screen” that process key press and audio player events. I’ve also added a “RunScreenSaver()” method that currently simply consists of a “print” so I can see if it’s being called. Eventually that will be replaced with code that draws an “roImageCanvas” with my custom screensaver content. I have also added the two screensaver settings to the manifest indicating a private screensaver. After the configured screensaver timeout, however, the default screensaver pops up, and my “RunScreenSaver()” method never gets called. Beyond implementing the entry point, and adding the settings to the manifest, I’m not sure what else I could be missing. The fact that the default screensaver works would suggest that there’s nothing specifically in my code that’s preventing the screensaver. I have no doubt that I’m missing something simple, but I can’t find any documentation in the SDK on how to implement a private screensaver (aside from the comment for the manifest setting), and there’re no examples, so I’m not sure where else to look than here. Thanks…

“TheEndless” wrote:
I’ve also added a “RunScreenSaver()” method that currently simply consists of a “print” so I can see if it’s being called. Eventually that will be replaced with code that draws an “roImageCanvas” with my custom screensaver content.

If RunScreenSaver() doesn’t contain an event loop, it’s probably just returning right away and falling out to the system screen saver. I just tried what you describe and got the same result. My print did not appear on the console and the default SS came on. Try putting up a blank canvas and implementing a simple event loop in RunScreenSaver().

“nowhereman” wrote:

“TheEndless” wrote:
I’ve also added a “RunScreenSaver()” method that currently simply consists of a “print” so I can see if it’s being called. Eventually that will be replaced with code that draws an “roImageCanvas” with my custom screensaver content.

If RunScreenSaver() doesn’t contain an event loop, it’s probably just returning right away and falling out to the system screen saver. I just tried what you describe and got the same result. My print did not appear on the console and the default SS came on. Try putting up a blank canvas and implementing a simple event loop in RunScreenSaver().
Hrmmm… well, that produced different behavior, which is encouraging, but not the expected behavior. Instead of getting the default screensaver, the screen went black… my code paints it blue and puts text on it, so it’s not mine. Interestingly, the wait loop on the screen that was up before the screensaver is still running, so I suspect the screensaver runs in different thread, which would explain why we don’t get prints to the console. See anything obviously wrong with this code?


Sub RunScreenSaver()
	print "screensaver"
	
	background = {
		Color: "#0000FF",
		TargetRect: { x: 0, y: 0, w: 1280, h: 720 }
	}
	text = { 
		Text: "Screensaver", 
		TextAttrs: {
			Color: "#FFFFFF",
			Font: "Large"
		},
		TargetRect:{ x: 0, y: 500, w: 1280, h: 35 } 
	}	
	
	msgPort = CreateObject( "roMessagePort" )
	screen = CreateObject( "roImageCanvas" )
	screen.SetMessagePort( msgPort )
	screen.SetRequireAllImagesToDraw( false )
	screen.AddLayer( 1, background )
	screen.AddLayer( 2, text )
	screen.Show()

	While true
		msg = Wait( 1000, msgPort )
		If msg.isRemoteKeyPressed() Then
			screen.Close() 
			Return
		End If
	End While	
End Sub

“TheEndless” wrote:
See anything obviously wrong with this code?


Sub RunScreenSaver()
	print "screensaver"
	
	background = {
		Color: "#0000FF",
		TargetRect: { x: 0, y: 0, w: 1280, h: 720 }
	}
	text = { 
		Text: "Screensaver", 
		TextAttrs: {
			Color: "#FFFFFF",
			Font: "Large"
		},
		TargetRect:{ x: 0, y: 500, w: 1280, h: 35 } 
	}	
	
	msgPort = CreateObject( "roMessagePort" )
	screen = CreateObject( "roImageCanvas" )
	screen.SetMessagePort( msgPort )
	screen.SetRequireAllImagesToDraw( false )
	screen.AddLayer( 1, background )
	screen.AddLayer( 2, text )
	screen.Show()

	While true
		msg = Wait( 1000, msgPort )
		If msg.isRemoteKeyPressed() Then
			screen.Close() 
			Return
		End If
	End While	
End Sub

AddLayer() is not a member of roImageCanvas. It should be SetLayer().

“nowhereman” wrote:
AddLayer() is not a member of roImageCanvas. It should be SetLayer().
Ugh… I knew that… I guess the runtime error on that one was posted to the other thread as well. :face_with_tongue:

That was it. Thanks for your help! I really appreciate it!

Steve

Ok.. new issue. With the screensaver, I never seem to get the IsScreenClosed() event that the Clock SDK example suggest I should. In fact, I never seem to get any events in my wait loop. In general, that’s not a big deal for the screensaver, but my app seems to lose focus when the screensaver comes up, and I never get it back. I don’t know if they’re related or not, but I suspect it has something to do with my wait loop never exiting, because I have no way to detect when the screensaver is closed. Any ideas?

Scratch that. It seems the same thing happens when the default screensaver is used. I’ll start a new thread.