{"id":8,"date":"2007-02-04T14:14:18","date_gmt":"2007-02-04T22:14:18","guid":{"rendered":"http:\/\/www.viscerallogic.com\/programming\/blog\/2007\/02\/04\/desktop-screensaver-background\/"},"modified":"2013-01-07T19:03:00","modified_gmt":"2013-01-08T03:03:00","slug":"desktop-screensaver-background","status":"publish","type":"post","link":"https:\/\/www.viscerallogic.com\/programming\/blog\/desktop-screensaver-background\/","title":{"rendered":"Desktop Screensaver Background"},"content":{"rendered":"<p>The screensaver module in OS X has a command-line option that allows it to be run in the<br \/>\nbackground of your screen, as a replacement for the desktop picture. I found this in the<br \/>\napplication <a href=\"http:\/\/macupdate.com\/info.php\/id\/17986\">bgscreensaver,<\/a> which<br \/>\ncontains an AppleScript to launch the screensaver module in the background, using a shell<br \/>\ncommand found by Michael Coyle at <a href=\"http:\/\/www.resexcellence.com\">ResExcellence.<\/a><\/p>\n<p>While this is pretty cool in and of itself, I wanted something that would let me run one<br \/>\nscreensaver as the background, and have another one for my actual screensaver.<br \/>\n<!--more--><\/p>\n<p>So after poking around a bit, I found where OS X stores the screensaver preferences. Using this,<br \/>\nI extended the AppleScript to change to store the current screensaver, set the preferences<br \/>\nto use the slideshow screensaver, and point to a directory of pictures of my choice. Then<br \/>\nit launches the screensaverm module as the background, and restores the preferences for<br \/>\nthe actual screensaver. Running the script again turns the background screensaver off.<\/p>\n<p>The heart of the code, which launches the screensaver module in the background or turns<br \/>\nit off if it&#8217;s already running, is as follows:<\/p>\n<blockquote>\n<pre>set isrunning to do shell script \"ps -ax | grep ScreenSaver.framework | grep -v grep | awk '{print $1}'\"\r\n\r\nif isrunning is \"\" then\r\n\tdo shell script \"\/System\/Library\/Frameworks\/ScreenSaver.framework\/Resources\/\r\n\t\tScreenSaverEngine.app\/Contents\/MacOS\/ScreenSaverEngine -background &gt; \/dev\/null 2&gt;&amp;1 &amp;\"\r\nelse\r\n\tdo shell script \"kill -9 \" &amp; isrunning &amp; \" &gt; \/dev\/null 2&gt;&amp;1\"\r\nend if<\/pre>\n<\/blockquote>\n<p>The first line uses the <i>do shell script<\/i> command in AppleScript to execute the<br \/>\nfollowing text in a command shell. This string actually consists of several commands,<br \/>\npiped together with the <i>|<\/i> character. What this does is pass the output of one<br \/>\ncommand to the input of the next. In this way, each of these is chained to following<br \/>\ncommand, to continue processing.<\/p>\n<p>The first command, <i>ps -ax<\/i>, returns a list of all currently running processes. The<br \/>\nnext command, <i>grep ScreenSaver.framework<\/i>, takes this list and searches for one<br \/>\nthat is using the screensaver module. However, this will actually end up return two<br \/>\nprocesses: the screensaver, and the process that&#8217;s searching for the screensaver. The<br \/>\nsolution in this case is to search this next list (of two items), and remove the one<br \/>\nthat is actually just a search itself. This is done with <i>grep -v grep<\/i>, which,<br \/>\nbecause of the <i>-v<\/i> option, searches for lines that <i>don&#8217;t<\/i> match the argument,<br \/>\nin thise case, <i>grep<\/i>. Thus, what remains is the screensaver process if it is running,<br \/>\nor nothing if it is not. The final command in this chain is <i>awk &#8216;{print $1}&#8217;<\/i>. The<br \/>\nprogram <i>awk<\/i> is used to scan text for a pattern, and then do something with it. In<br \/>\nthis case, no pattern is specified, but the action is to print the first field it scans,<br \/>\nwhich in output from <i>ps<\/i> is the process ID.<\/p>\n<p>The reason the process ID is relevant is because of the behavior we want. If the<br \/>\nscreensaver is not currently running, we want it to start running. If it is running,<br \/>\nwe want it to stop running. From the command in the first line, the variable in the<br \/>\nAppleScript <i>isrunning<\/i> will be set to the process ID if the screensaver is<br \/>\nrunning, and to the empty string <i>&#8220;&#8221;<\/i> if it is not running. The if structure on<br \/>\nthe next few lines then takes the appropriate action.<\/p>\n<p>If the screensaver process is not running, it is launched by running another shell script.<br \/>\nThis shell command executes the <i>ScreenSaverEngine<\/i> executable code contained in the<br \/>\nlong path shown, inside the <i>ScreenSaver.framework<\/i> framework. The executable is<br \/>\npassed the argument <i>-background<\/i> in the command shell, which causes it to run as<br \/>\nthe desktop, instead of in front like a regular screensaver. The next bit in the line<br \/>\n(and everything between the two &#8221; characters should be on one line), <i>&gt; \/dev\/null<\/i>,<br \/>\ndirects all output from the <i>ScreenSaverEngine<\/i> executable to be ignored. The next<br \/>\nbit, <i>2&gt;&amp;1<\/i>, directs any error output to go the same place as the standard<br \/>\noutput, which in this case is to be ignored. Finally, the <i>&amp;<\/i> at the end allows<br \/>\nthe command shell to continue running without waiting for the process to end. Otherwise,<br \/>\nthe AppleScript would not finish. On the other hand, if the screensaver module <i>is<\/i><br \/>\ncurrently running, it is stopped with the <i>kill -9<\/i> command, which again has its<br \/>\noutput and errors ignored.<\/p>\n<p>So far, so good. If you have copied this text into the <i>Script Editor<\/i> application,<br \/>\nyou will be able to turn your desktop background into your screensaver by running this<br \/>\ncode, and revert to your regular desktop by running it again. But I found that I would<br \/>\nrather have a different moving background than my screensaver. So the next few lines of<br \/>\ncode will allow us to save the currently selected screensaver from the preferences and<br \/>\nchange it to one of our liking before running the screensaver module in the background.<br \/>\nIn this case, we will set it to the slide show screensaver, using a particular folder<br \/>\nof picture. You should paste these lines in <i>before<\/i> those above.<\/p>\n<blockquote>\n<pre>set screensaver to \"~\/Library\/Preferences\/ByHost\/\" &amp; (do shell script \"cd ~\/Library\/\r\n\tPreferences\/ByHost;ls | grep 'com\\\\.apple\\\\.screensaver\\\\..\\\\{12\\\\}\\\\.plist' |\r\n\tsed 's\/\\\\.plist\/\/'\")\r\n\r\nset lastPictureDirectoryChosen to (do shell script \"defaults read \" &amp; screensaver &amp;\r\n\t\" lastPictureDirectoryChosen\")\r\n\r\nset modulePath to (do shell script \"defaults read \" &amp; screensaver &amp; \" modulePath\")\r\n\r\ndo shell script \"defaults write \" &amp; screensaver &amp; \" lastPictureDirectoryChosen \r\n\t\/Users\/paul\/Pictures\/Airplanes\"\r\n\r\ndo shell script \"defaults write \" &amp; screensaver &amp; \" modulePath \\\"\/System\/Library\/\r\n\tFrameworks\/ScreenSaver.framework\/Resources\/Pictures Folder.saver\\\"\"<\/pre>\n<\/blockquote>\n<p>Each of these should actually be a single line. The Script Editor will perform<br \/>\nautomatic line breaking and indenting similar to what is shown here, depending on the<br \/>\nsize of your window.<\/p>\n<p>The first line sets the variable <i>screensaver<\/i> to the file path of your screensaver<br \/>\npreferences file. You may notice that it involves another shell script. This is because<br \/>\nthere is not a fixed file name for the screensaver preferences. For whatever reason,<br \/>\nApple placed the screensaver preferences in the <i>ByHost<\/i> directory, where the files<br \/>\nall include your ethernet address in the name. Consequently, we have to find the file<br \/>\nwithout knowing its exact name. This is fairly simple using <i>grep<\/i> again, however,<br \/>\nsince we know the format for the name. The name will be <i>com.apple.screensaver.<\/i><br \/>\nfollowed by the address followed by <i>.plist<\/i>. The address is twelve characters long.<br \/>\nSo the grep pattern here searches for the first part of the file name, followed by any<br \/>\ntwelve characters, followed by the extension. A period has a special meaning for a<br \/>\nregular expression matcher, such as <i>grep<\/i>. It means that it can match any character.<br \/>\nConsequently, to match a period, you have to <i>escape<\/i> it by placing a <i>\\<\/i> in<br \/>\nbefore it. But a <i>\\<\/i> also has special meaning in AppleScript, so you first have to<br \/>\nescape the back slash in AppleScript by using <i>\\\\.<\/i>, which will pass along to the<br \/>\ncommand shell to be passed to grep: <i>\\.<\/i> . Now, we wouldn&#8217;t really need to escape<br \/>\nthe periods, since they would match anyway, but I did for demonstration purposes.<\/p>\n<p>The next line makes use of the OS X tool <i>defaults,<\/i> which reads and writes the<br \/>\nXML-based preference files used throughout OS X. In this case, it reads the property<br \/>\nnamed <i>lastPictureDirectoryChosen<\/i> from the screensaver preference file we located<br \/>\nin the previous line. The <i>lastPictureDirectoryChosen<\/i> property contains the file<br \/>\npath to the last folder the user set to use with the picture slideshow screensaver. We<br \/>\nneed to save this because it is one of the things we&#8217;ll be changing to supply our own<br \/>\nfolder of pictures.<\/p>\n<p>The next line also makes use of the <i>defaults<\/i> functionality, this time reading in<br \/>\nwhat actual screensaver module the user currently has set. We need to save this because<br \/>\nwe will be setting this to the slideshow screensaver, regardless of what it is currently<br \/>\non.<\/p>\n<p>Next we use <i>defaults<\/i> to <i>write<\/i> to the preference files. First we update the<br \/>\n<i>lastPictureDirectoryChosen<\/i> property, setting it to the file path of the folder in<br \/>\nwhich you want all the pictures to be displayed as your background. In my case, it is set<br \/>\nto a folder of airplane pictures. You can hard code this value, as I did here, or you<br \/>\ncould make it a user input when the application is run, allowing you to specify each time<br \/>\na potentially different folder with pictures.<\/p>\n<p>The last line in this block sets the preference for the screensaver to use the <i>Pictures<br \/>\nFolder<\/i> screensaver. You can see there are more back-slashes in this line. That&#8217;s<br \/>\nbecause the path has spaces in it, and so must be within quotes. But if you just typed<br \/>\na quote, that would end the string in the AppleScript, so you have to escape it with<br \/>\n<i>\\&#8221;<\/i>.<\/p>\n<p>If you ran the AppleScript with these new lines pasted above the earlier lines (with the<br \/>\npicture folder path set properly for your computer), your background would become an<br \/>\nanimated slideshow of the pictures in that folder. However, this would also set your<br \/>\nactual screensaver to the same slideshow! What you need to do after starting the screensaver<br \/>\nmodule is restore the information you saved previously. That is what these final lines<br \/>\naccomplish:<\/p>\n<blockquote>\n<pre>do shell script \"sleep 2; defaults write \" &amp; screensaver &amp; \r\n\t\" lastPictureDirectoryChosen \" &amp; \"\\\"\" &amp; lastPictureDirectoryChosen &amp; \"\\\"\"\r\n\r\ndo shell script \"defaults write \" &amp; screensaver &amp; \" modulePath \" &amp; \"\\\"\" &amp; modulePath &amp; \"\\\"\"<\/pre>\n<\/blockquote>\n<p>The first line executes another shell command. Actually, it&#8217;s two commands combined, but<br \/>\nnot piped together this time. The semicolor after <i>sleep 2<\/i> indicates to the shell<br \/>\nprocess that these are two different commands. The reason we have the <i>sleep<\/i> command<br \/>\n(which in this cases causes the shell to wait for 2 seconds before continuing to execute<br \/>\nthe next command on the line) is that we started the screensaver executable with the<br \/>\n&amp; option, which means the shell won&#8217;t wait for it to finish executing. One consequence<br \/>\nof this is that we could potentially be restoring the user preferences before the background<br \/>\nscreensaver actually reads the new values we wanted to supply. So we wait two seconds<br \/>\nbefore restoring the saved preferences. There are quotes again around the<br \/>\n<i>lastPictureDirectoryChosen<\/i> because we don&#8217;t know what the value is, and there may<br \/>\nbe spaces or other strange characters in there, so the shell might interpret it other than<br \/>\nthe way we want. Placing it in quotes (escaped for AppleScript, of course), ensures that<br \/>\nit will be treated as the path we want.<\/p>\n<p>The last line, then, restores users actual screensaver preference.<\/p>\n<p>Now when you put this together, it will read and save the user&#8217;s system screensaver<br \/>\npreferences, write the proper values for the screensaver you want to run in the background,<br \/>\nand restore the user&#8217;s preferences after waiting two seconds to ensure the background<br \/>\nvalues will be read. Running it again will kill the background screensaver and revert<br \/>\nto whatever your normal desktop is. The finished source code is available<br \/>\n<a href=\"http:\/\/www.viscerallogic.com\/programming\/files\/Slideshow BG.applescript\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The screensaver module in OS X has a command-line option that allows it to be run in the background of your screen, as a replacement for the desktop picture. I found this in the application bgscreensaver, which contains an AppleScript to launch the screensaver module in the background, using a shell command found by Michael [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[9,5,10],"tags":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9npkn-8","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":10,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/smultron-code-editor\/","url_meta":{"origin":8,"position":0},"title":"Smultron Code Editor","date":"May 16, 2007","format":false,"excerpt":"In developing software, the choice of tools used can affect the ease of the job significantly. While the choice of a language may dictate the compiler to be used, there are generally a number of options for the code editor. For most C, Objective-C, and Java applications, I use Apple's\u2026","rel":"","context":"In &quot;OS X&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/compiling-with-gfortran\/","url_meta":{"origin":8,"position":1},"title":"Compiling with gfortran","date":"November 18, 2006","format":false,"excerpt":"I compiled XFoil earlier today for my Mac. XFoil is an open-source airfoil analysis tool. There are various compiled binaries available for Windows systems, but for Unix computers, including Mac OS X, it must be built from the source code. This requires the use of a Fortran compiler. To build\u2026","rel":"","context":"In &quot;Fortran&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":39,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-i\/","url_meta":{"origin":8,"position":2},"title":"BASIC Interpreter, Part I","date":"September 7, 2018","format":false,"excerpt":"This is the first of a multi-post tutorial on using flex and Bison to write a programming language interpreter, in this case, BASIC. We'll be using the 1964 BASIC manual from Dartmouth as the starting point language reference. All code is available at this GitHub repository: https:\/\/github.com\/VisceralLogic\/basic. The interpreter will\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/numerical-expression-solver-in-java\/","url_meta":{"origin":8,"position":3},"title":"Numerical Expression Solver in Java","date":"November 12, 2005","format":false,"excerpt":"This tutorial will show you how to write a Java program that takes a string input such as \"3 + 4^2*7.5E-1*sin(22)\" and convert it into a numerical answer, 2.893784 in this case, which you can use for whatever purpose you like. This Java Applet utilizes the Expression class that you\u2026","rel":"","context":"In &quot;Java&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":131,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-vi\/","url_meta":{"origin":8,"position":4},"title":"BASIC Interpreter, Part VI","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part V. In the previous section, we added support for the GOTO statement. Since we don't yet have any control logic, that is not very useful, but it does lay the infrastructure for one of the features we will add this time: IF-THEN. We will\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/variables-and-graphical-plots-in-java\/","url_meta":{"origin":8,"position":5},"title":"Variables and Graphical Plots in Java","date":"November 17, 2005","format":false,"excerpt":"This tutorial builds on the Numerical Expression Solver tutorial, adding textual variables such as \"e\" or \"pi\", and custom ones. Then you will create an applet that takes advantage of this new functionality by creating a graphical representation of an arbitrary expression at each point in space. This applet is\u2026","rel":"","context":"In &quot;Java&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/8"}],"collection":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/comments?post=8"}],"version-history":[{"count":3,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/8\/revisions"}],"predecessor-version":[{"id":15,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/8\/revisions\/15"}],"wp:attachment":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/media?parent=8"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/categories?post=8"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/tags?post=8"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}