USE SURF WITHOUT A WELDING HELMET
       
       Who here has lived to use `surf' in a darkened room and lived to tell
       the tale? I have, though my eyes are worse for wear for it.
       
       I'd been told it was a character building exercise: that momentary
       flash of white while `surf' loads a webpage will put hair on your
       chest, turn your automatic Subaru into a manual Honda Civic, and get
       your wife pregnant. Sure, the character of my cataracts was developing
       at a positively accelerated rate.
       
       I'd considered getting out the welding helmet, or else timing my
       blinks to coincide with that momentary blast of #FFFFFF just to avoid
       shock. I'd also done my customary web search to learn how to enable
       darkmode in `surf'. I found halfway answers: stylesheets would make
       the loaded page show in a darkmode. But still: a blinding whitescreen
       between when `surf' launches and when WebKit has finished loading the
       page persists.
       
       ,----
       | /* Place these styles inside ~/.surf/styles/default.css to get
       |    darkmode on every website. Code adapted from:
       |    https://surf.suckless.org/stylesheets/darkmode_css/ */
       | *,div,pre,textarea,body,input,td,tr,p {
       |     background-color: #000000 !important;
       |     background-image: none !important;
       |     color: #bbbbbb !important;
       | }
       | h1,h2,h3,h4 {
       |     background-color: #000000 !important;
       |     color: #b8ddea !important;
       | }
       | img {
       |     opacity: .5;
       | }
       | img:hover {
       |     opacity: 1;
       | }
       `----
       
       I decided to clone the repo and dig around the code for opportunities
       to extinguish the flame. To get things building properly on Void I had
       to install two new dependencies: `webkit2gtk-devel' and `gcr-devel'.
       
       I started my playing around by commenting out some code and adding
       print statements to see what runs where. Towards the bottom of
       `surf.c' I found that if I only invoked `showview' I could preserve
       that blinding whitescreen forever as long as the program is running
       (nice!).
       
       ,----
       | c = newclient(NULL);
       | showview(NULL, c);
       | /* loaduri(c, &arg); */
       | /* updatetitle(c); */
       | /* gtk_main(); */
       | /* cleanup(); */
       `----
       
       That lead me to look into `showview'. Immediately I noticed the
       `bgcolor' variable. I tried changing it from `GdkRGBA bgcolor = { 0
       };' to `GdkRGBA bgcolor = { 1,0,0,1 };', using full-on red just as a
       test so I could see it. It made no difference. From here I went to the
       `createwindow' function, which is called from inside `showview'. I
       noticed that this function creates the GTK window which eventually
       contains the WebKit view. I found a place to set the default
       background color of the GTK window to black. After a `make', I found
       that this eliminated most of the white screen. `surf' launched in
       black, momentarily showed white, and then loaded the page.
       
       ,----
       | GtkWidget *
       | createwindow(Client *c)
       | {
       |       char *wmstr;
       |       GtkWidget *w;
       |       if (embed) {
       |               w = gtk_plug_new(embed);
       |       } else {
       |               w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
       |               wmstr = g_path_get_basename(argv0);
       |               gtk_window_set_wmclass(GTK_WINDOW(w), wmstr, "Surf");
       |               g_free(wmstr);
       |               wmstr = g_strdup_printf("%s[%"PRIu64"]", "Surf", c->pageid);
       |               gtk_window_set_role(GTK_WINDOW(w), wmstr);
       |               g_free(wmstr);
       |               gtk_window_set_default_size(GTK_WINDOW(w), winsize[0], winsize[1]);
       |                 # Black bg
       |               gtk_widget_modify_bg(GTK_WINDOW(w), GTK_STATE_NORMAL, &(GdkColor){0});
       |       }
       `----
       
       From here, I went back to the `main' function and manually traced the
       function invokations below `showview'. This lead me to a few functions
       of interest: `loaduri', `loadchanged', and `newview)'.
       
       I soon understood the order of the presentation: the GTK window was
       created first, then it was filled with the WebKit view. WebKit loads
       the uri with `webkit_web_view_load_uri(c->view, url);' and then there
       are various loading signals from `WEBKIT_LOAD_STARTED' to
       `WEBKIT_LOAD_FINISHED'. I'd taken care of setting the GTK window
       background to black, thus achieving an amount of success. But the
       WebKit view stayed white while the page loaded. My quest to be fully
       enveloped by darkmode continued.
       
       For a while, my hypothesis was that I needed to adjust something
       around the WebKit load signals or maybe introduce my darkmode CSS
       stylesheet earlier, somehow, to get rid of the white flash that
       remained between the GTK window and the WebKit view. Maybe, I thought,
       the WebKit view allowed CSS styles even before the page loaded.
       
       I peeked back into the `newview' function and noticed therein how settings were applied to the WebKit view. I added `setstyle(c, getstyle(geturi(c)));' just before the return statement, thinking this stylesheet would avoid the whitescreen in the WebKit view. That didn't work, but I noticed this nearby: `setparameter(c, 0, DarkMode, &curconfig[DarkMode].val);' I found that this value could be set from `config.h'. I set the value to `1' and recompile under bated breath. Still no full darkmode.
       
       Now I'm a bit hazy about what happened next. I was in a frenzy!
       (Family and friends be damned that I didn't answer the phone for I was
       `hacking'!) But it seems that in the moment of despair that followed
       failure I dragged myself back to `showview'. I played with the
       `bgcolor' variable again, then looked more closely at the `showview'
       function's logic. The prize that I sought stood out like a toad in a
       hole:
       
       ,----
       | if (curconfig[HideBackground].val.i)
       |         webkit_web_view_set_background_color(c->view, &bgcolor);
       `----
       
       I moved briskly over to `config.h' and set `HideBackground' to `1'. I
       `make''d and ... voila! No blinding whitescreen of fire! I had found
       my full darkmode. It seems that setting the WebKit view background to
       a `GdkRGBA bgcolor = { 0 }' (as happens when the statement above
       evaluates) causes the view to have a black background. Combined this
       with the GTK window set with a black background and the whitescreen is
       entirely avoided.
       
       
       Summary
       ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       To effect pretty good darkmode in `surf' (it will show a gray fill
       while the GTK window is built and the WebKit view loads), do the
       following:
       
       1. Clone the repo. Install dependencies and get a successful `make'.
       2. Modify `config.h' so `HideBackground' and `DarkMode' are both set to
          `{ .i = 1 }'
       3. Create a default stylesheet at `~/.surf/styles/default.css' including
          the aforementioned darkmode styles.
       4. Build surf.
       5. Put away your welding helmet.
       
       To effect an even better darkmode in `surf' (it will show a black fill
       from launch up until page load), do the above *and* add the following
       snippet to line 1464, just before `createwindow' returns.
       
       ,----
       | gtk_widget_modify_bg(GTK_WINDOW(w), GTK_STATE_NORMAL, &(GdkColor){0});
       `----
       
       
       Patch
       ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       Below is a patch you can apply. Note that you'll still need to
       manually add a stylesheet to affect darkmode on the websites you
       visit. This patch only eliminates the whitescreens during `surf''s
       launch and load procedures.
       
       ,----
       | From 25fedb98bc24067ce04d6b9daa49b4950ea4d3a2 Mon Sep 17 00:00:00 2001
       | From: Scarlett McAllister <no+reply@roygbyte.com>
       | Date: Thu, 28 Dec 2023 13:44:21 -0400
       | Subject: [PATCH] Add darkmode to GTK window
       | ---
       |  config.def.h | 4 ++--
       |  surf.c       | 1 +
       |  2 files changed, 3 insertions(+), 2 deletions(-)
       | diff --git a/config.def.h b/config.def.h
       | index 93cfeeb..0214d6e 100644
       | --- a/config.def.h
       | +++ b/config.def.h
       | @@ -20,7 +20,7 @@ static Parameter defconfig[ParameterLast] = {
       |         [Certificate]         =       { { .i = 0 },     },
       |         [CaretBrowsing]       =       { { .i = 0 },     },
       |         [CookiePolicies]      =       { { .v = "@Aa" }, },
       | -       [DarkMode]            =       { { .i = 0 },     },
       | +       [DarkMode]            =       { { .i = 1 },     },
       |         [DefaultCharset]      =       { { .v = "UTF-8" }, },
       |         [DiskCache]           =       { { .i = 1 },     },
       |         [DNSPrefetch]         =       { { .i = 0 },     },
       | @@ -29,7 +29,7 @@ static Parameter defconfig[ParameterLast] = {
       |         [FontSize]            =       { { .i = 12 },    },
       |         [FrameFlattening]     =       { { .i = 0 },     },
       |         [Geolocation]         =       { { .i = 0 },     },
       | -       [HideBackground]      =       { { .i = 0 },     },
       | +       [HideBackground]      =       { { .i = 1 },     },
       |         [Inspector]           =       { { .i = 0 },     },
       |         [Java]                =       { { .i = 1 },     },
       |         [JavaScript]          =       { { .i = 1 },     },
       | diff --git a/surf.c b/surf.c
       | index f8c8dec..a6cb224 100644
       | --- a/surf.c
       | +++ b/surf.c
       | @@ -1461,6 +1461,7 @@ createwindow(Client *c)
       |         g_signal_connect(G_OBJECT(w), "window-state-event",
       |                          G_CALLBACK(winevent), c);
       | 
       | +       gtk_widget_modify_bg(GTK_WINDOW(w), GTK_STATE_NORMAL, &(GdkColor){0});
       |         return w;
       |  }
       | 
       | -- 
       | 2.42.0
       `----