Creating Mac-like dynamic wallpaper in Windows using Python3 from scratch

First, I want to tell you something. Today I’m writing for the first time on Medium. Thus, I’m a bit nervous, as well as quite excited. Pardon me (in advance) if I made any mitsake (especially grammatical) :(

When Apple announced Mac OS Mojave, back in September 2018, people got over-hyped for the “dark mode” in newly introduced Mac OS Mojave. And, they completely ignored (like you’ve ignored “mitsake” as “mistake” in the previous paragraph) other exciting features, like “Dynamic Wallpaper” etc. And, proudly I can say, I was one of them.

Being a hardcore Windows-user (since my diaper-days), I got fascinated when I saw this video today on my youtube recommendations.

After watching this, I took a coding challenge, to recreate, one like this, for windows. Oh, by the way, I am a self-taught programmer with no CS background (even in my school days). So, my code might have the power to create smile (better to say, laught) on your face :)


  1. Digging up Raw Materials for this project:

As the name suggests, the main ingredients for this project are Wallpapers of Mac OS Mojave. So, with a lot of hope, I started browsing to get a bunch of Kelso Dunes wallpaper for my project. But, after when did see that, only 16 of them are available, throughout the internet, I gave up my plan to use official wallpapers for my project.

i. There is always a ‘Plan B’:

I downloaded that 17 sec 4K 30 fps video from youtube and planned to use each frame as the desktop wallpaper to get a more naturalistic look. But, alas! I didn’t know that Adobe Premiere Pro doesn’t support frame extraction from .mkv format. So, I converted the video to mp4 and extracted 17x30 = 510 frames from it.

2. It’s Coding time:

i. Too BIG to type:

After extracting the frame, the very first thing, I’d noticed is their king-kong type names. So, I fired up my Python IDLE and type:

import os
path = '/Users/amlan/Desktop/mojave'
files = os.listdir(path)
for index, file in enumerate(files):
os.rename(os.path.join(path, file), os.path.join(path, ''.join(["wp"+str(index), '.jpg'])))

..and voila! Within a blink of an eye, it has turned into…

Quite tidy, I guess :)

ii. Logic is everything:

As we’re tending towards our goal, we have to build up a crisp logic before writing long code. So, first I observe a few things:

  1. We have 510 frames (a.k.a our wallpapers) for 60x60x24=86400 sec.
  2. Means, we have to set 86400/510 = 169.41 spf (second per frame) for our wallpapers to get an evenly distributed view.
  3. We do not log in to our system at the exact same time, every day.
  4. The sky of the very first wallpaper (wp0) seems like 3–4 hr. prior to sunrise.
  5. The time of sunrise is not constant throughout the year.
  6. Comparing Summer and Winter Solstice, we can get a rough idea about the sunrise and sunset time as follows..

iii. Down the coding lane…

So, keeping these things to our mind, I wrote this code in Python:

import datetime,ctypes, timex = TIME
CMonth = int(x.strftime("%m"))
#Starting Hr Calculation
if CMonth <=3 or CMonth >=9:
startH = 2
startH = 3
#TIME FROM Starting Hour
if CH >= startH:
calH = CH-startH
calH = CH+24-startH
upSec = calH*3600+CM*60+CS
startSec = int(upSec//169.4)
val = 510
num = 169.
n = startSec%510
while n < int(val)+1:
path = "C:\\Users\\amlan\\Desktop\\mojave\\wp"+str(n)+".jpg"
y =
if n == int(val)+1:
n = 1

Allow me to give a brief explanation of my code.

First I import datetime module to extract the present month (point no. 5:The time of sunrise is not constant throughout the year. ) as well as current time (3.We do not log in to our system at the exact same time, every day). Then, based on the data from point 6, we fixed two different starting hours (Dynamic) for our (Static) set of wallpapers. Then we calculate the position of our first wallpaper, based on the current time and starting hour. After deciding the initial wallpaper, I just keep setting the next wallpaper after a fixed interval of 169 sec.

Tadaaaaa…….. My job is done. Now, let’s see a few outcomes.

iv. Last but not least…

I forgot to mention one thing. Save the main python script as .pyw extension, so that, we can easily add them at the time of starting up our system.

Moral of today’s journey: Where there is a will, there’s a way. :)

Well….thank you so much for tolerating me so far. I’d love to hear any suggestions regarding anything from you. Don’t hesitate to share any tips to this newcomer. See you again soon.

Till then, Bye bye…….



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Amlan Saha Kundu

Amlan Saha Kundu

Mathematician | Self-taught Programmer | Photographer | Designer | Dedicated Chess player | Former intern @ Google AI