surfdemystified.html 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width, initial-scale=0.65"/>
  5. <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
  6. <meta content="Steve Litt" name="author"/>
  7. <meta name="keywords" content="Linux,browser,surf,suckless"/>
  8. <meta name="description" content="Using the surf browser."/>
  9. <title>Surf Demystified</title>
  10. <link href="linuxlibrary.css" type="text/css" rel="stylesheet"/>
  11. <style type="text/css">
  12. div.utpcenterer thead{font-weight: bold; font-size: 110%;}
  13. span.itemtitle{background-color: #ccffcc;}
  14. body{font-size: 100%;}
  15. div.collist{display: inline-block; vertical-align: text-top;}
  16. html{zoom: 100%;}
  17. img.w400{width="100%"; max-width="300px"; margin="0px"; padding="0px";}
  18. table#keystrokes td{border-bottom-style: solid; border-bottom-width: 2px;}
  19. table#keystrokes td{padding-bottom: 1ex; padding-top: 1ex; padding-right: 0.5em; vertical-align: middle;}
  20. ul.contents li{padding-bottom: 0.1ex; padding-top: 0.1ex; margin-bottom: 0.1ex; margin-top: 0.1ex;}
  21. </style>
  22. <link href="../monthfea.css" type="text/css" rel="stylesheet" />
  23. <script language='javascript' src='../monthfea.js'></script>
  24. </head>
  25. <body onload="loaddiv()" >
  26. <div class="utpcenterer">
  27. <div class="midcolumn">
  28. <p class="presents"><a href="../troubleshooters.htm">Troubleshooters.Com</a><sup class="tm">&#174;</sup>,
  29. <a href="./index.htm">Linux Library</a> Present:</p>
  30. <p class="title">Surf Demystified</p>
  31. <p class="copyright"><a href="../cpyright.htm">Copyright <span
  32. class="copyright_symbol">&#169;</span> 2017</a> by Steve Litt</p>
  33. <div class="monthfea" id="monthfea">
  34. <p class="monthfea">See the <a href="http://www.troubleshooters.com/bookstore/">Troubleshooters.Com Bookstore</a>.</p>
  35. </div>
  36. <p class="contents_title">Contents:</p>
  37. <ul class="contents">
  38. <li><a href="#introduction">Introduction</a></li>
  39. <li><a href="#andtabbed">Surf and Tabbed</a></li>
  40. <li><a href="#surfpkgmgr">Installing Surf With a Package Manager</a></li>
  41. <li><a href="#surfhotkeys">Surf Hotkeys</a></li>
  42. <li><a href="#keyboardonly">Keyboard-Only Surf Usage</a></li>
  43. <li><a href="#linkhints">Link Hints</a></li>
  44. <li><a href="#modsurf">Modifying Surf</a></li>
  45. <li><a href="#surfconfigdetails">Surf Configuration Details</a></li>
  46. <li><a href="#installingtabbed">Installing Tabbed</a></li>
  47. <li><a href="#cmdexpl">Explanation of Commands</a></li>
  48. <li><a href="#modtabbed">Modifying Tabbed</a></li>
  49. <li><a href="#mouseprimary">Mouse-primary Surf Usage</a></li>
  50. <li><a href="#integration">Integrating Tabbed and Surf With Other Programs</a></li>
  51. <li><a href="#sucklessadvantage">The Suckless Tools Advantage</a></li>
  52. <li><a href="#acquiredtaste">Surf: An Acquired Taste</a></li>
  53. <li><a href="#wrapup">Wrapup</a></li>
  54. </ul>
  55. <h1 id="introduction">Introduction</h1>
  56. <p>This is a long document because it's the only <em>complete</em> documentation for the Surf browser. This is a necessary document because other browsers have become so rickety that Surf has become the go-to browser for anyone willing to use a simple, keyboard-centric interface.</p>
  57. <p>Surf is a simple, lightweight browser from Suckless Tools, the same people who brought you dmenu and dwm. When compiled and configured right, Surf is incredibly robust and stable, able to handle most websites extremely well, and it has a clean and simple layout without buttons and bars to encroach on the web material you're reading. Unfortunately, Surf is underdocumented, so most who try Surf give up after a few minutes, moving on to Firefox or Chromium or Palemoon or Midori. This web page serves as the needed documentation to make Surf a pleasure to work with.</p>
  58. <p>Surf gains a new credibility and significance now (2017), because in 2017, most browsers have declined in stability and performance, over the last several years, to the point where several of them are unusable on various distros. We all know Firefox is now skating on the edge of uselessness, at least on several distros. Palemoon, the "lighter Firefox", has performance problems that frequently drag the whole computer almost to a standstill. Midori, Luakit, Xombrero and most of the other Webkit derived browsers intermittently abort suddenly, at least when hosted on Void Linux. I'm having some success with Chromium, but it's piggy and often quirky. If you're anything like me, these days browsers are exhibiting ever worsening flaws, so that ever more frequently you need to once again switch browsers to one that sucks just a little less than the others.</p>
  59. <p>Meanwhile, over the past few years, the Surf browser has acquired CSS and Javascript abilities, so it now renders as well as, and very similarly to, any of the big boys. And if you run it right, it's stable: More stable than most of the usual suspects: Especially Firefox and Palemoon. So now, with the big boys defaulting on stability and performance, Surf begins to look like the best of the bunch, at least for general purpose browsing.</p>
  60. <p>Of course Surf isn't perfect. I found no obvious way to use SSL with Surf, although the source code appears to have some code related to SSL. Maybe you can get it to work with SSL, but lacking both a URL bar and that cool little lock icon, I wouldn't do online banking, shopping or bill paying with Surf. Because in some environments using Surf with plugins producing the dreaded "program vanished" Webkit bug, many folks can't use Surf with plugins such as ad blockers. Also, the only way to configure Surf is to recompile it, and many folks prefer to use the version installed by their package manager. And typically, the package manager version has small, low contrast fonts used to acquire URLs, requiring modification by anyone with bad vision. And when you modify by recompilation, you'll find that Surf depends on a surprising number of other software you might not have installed.</p>
  61. <p>With no URL field, no button bar, and no back button, Surf isn't mouse-friendly without adding some <a href="#mouseprimary">user addable features</a> discussed toward the end of this document.</p>
  62. <p>This out of the box keyboard-centricity is fine: Keyboard productivity is much higher than mouse productivity. But Surf lacks keyboard-accessibility in one critical browsing activity: Navigating to and following links. So as Surf ships from the factory, you need to keep switching from mouse to keyboard: A guaranteed productivity killer. Surf documents a Javascript implementation of "link hinting": A functionality by which, when invoked, all visible links are numbered and you can follow them by typing in the number. Unfortunately, the javascript solution Suckless Tools gives you works on some web pages and not others. Later in this document you'll be given a 12 line piece of Javascript that makes Surf's Javascript solution work every time. Also given later in this document is a way to make the Grave accent key into the equivalent of a back button, so you can keep mousing with your right hand while easily going back in history with your left. </p>
  63. <p>Surf has no URL field, so neither copying nor pasting the URL is obvious. It does, however, have hotkeys for copying the current URL into the clipboard (Ctrl+y), and navigating to the URL currently in the clipboard (Ctrl+p). Surf doesn't have the handy URL completion that most modern browsers have, and this is the one missing productivity feature you can't make up for with creative configuration.</p>
  64. <p>Surf is very, very different from most browsers. It's an acquired
  65. taste, and most of us would prefer Firefox as it existed in 2010, or
  66. even Galeon from 2005. But those choices are gone now: Firefox is sand
  67. saturated molasses. So is Firefox's "lighter" little brother Palemoon,
  68. and when hosting a few tabs with challenging web pages, both give your
  69. computer that Windows 95 pacing from the days of the Pentium 1 with 64
  70. <strong>M</strong>B of RAM. Galeon is gone, and its descendants are part of the Gnome3 universe, with Gnome (along with its FreeDesktop siblings including systemd) becoming more of an "in for a penny, in for a pound" type thing. It's beginning to look like Surf is the last good browser standing.</p>
  71. <p>Yes, most of us would prefer 2010 Firefox, but for the past three or four years a lot of us have been switching browsers often -- every time our favorite one broke. And many of us use different browsers for different things. And I think that's where Surf comes in: A great browser for generic web viewing and Youtube videos. For secure online transactions you'd probably use Firefox (it works OK if used on one website at a time) or Chromium. Or, if yours isn't one of those distros with the webkit arbitrary abort problem, Midori, Luakit, Xombrero or any number of other lightweight browsers work quite well. To reiterate, what separates Surf from the other Webkit driven lightweights is that with Surf you can fix those aborts.</p>
  72. <p>Let me reiterate: Firefox and Chromium work quite well if you use them only for online secure transactions, while offloading generic browsing, and especially videos, to lightweight browsers like Surf. Just don't give heavy work to Chromium, or especially Firefox.</p>
  73. <p>One of the best things about Surf is its simplicity. The C code compiles with a minimum of fuss, and missing dependencies (mostly devel packages) are easy to deduce from compile error messages. If things get squirrelly, you can look at the (easy) source code or change it. Configuration is as simple as changing the <span class="code">config.h</span> file and recompiling.</p>
  74. <p>If you like operating your browser from the keyboard, you're going to love Surf. Almost everything that could be done can be done with hotkeys, and it's quite easy to modify <span class="code">config.h</span> to give yourself new hotkeys.</p>
  75. <p>Another nicety of Surf is an acquired taste: Lacking all buttons and bars, Surf devotes every square millimeter to the content you're viewing. It does this by offloading the functionalities of all those buttons to hotkeys, which usually turns out to be faster than mousing them. Use Surf for a couple weeks, then go back to Firefox, and you'll feel like you're viewing the web through a little peep hole.</p>
  76. <p>This is 2017, we're rapidly getting to the point where browsers are like email clients: They all suck. In this environment, the Surf browser, which sucks a lot less than the rest, takes on a new importance.</p>
  77. <h1 id="andtabbed">Surf and Tabbed</h1>
  78. <p>Surf is limited to looking at one website at a time, like the browsers from 1996. Don't worry though: With the addition of another Suckless Tools program called Tabbed, you can have the equivalent of a tabbed browser. The command is simple enough:</p>
  79. <pre class="code">tabbed surf -pe</pre>
  80. <p>The following hotkeys then control your tabbing:</p>
  81. <ul>
  82. <li><span class="code">Shift+Ctrl+Enter</span>: New tab</li>
  83. <li><span class="code">Shift+Ctrl+l</span>: Next higher number tab</li>
  84. <li><span class="code">Shift+Ctrl+h</span>: Next lower number tab</li>
  85. <li><span class="code">Ctrl+Tab</span>: Toggle between last 2 tabs</li>
  86. <li><span class="code">Ctrl+1</span>: Switch to tab 1</li>
  87. <li><span class="code">Ctrl+2</span>: Switch to tab 2</li>
  88. <li><span class="code">Ctrl+3</span>: Switch to tab 3, etc.</li>
  89. <li><span class="code">Ctrl+q</span>: Close this tab</li>
  90. <li><span class="code">Ctrl+t</span>: Tab picklist</li>
  91. </ul>
  92. <p>As long as we're on the subject of hotkeys, here are a few hotkeys for Surf survival:</p>
  93. <ul>
  94. <li><span class="code">Ctrl+g</span>: Go to URL (field on screen's upper left (not the browser window) opens for you to type)</li>
  95. <li><span class="code">Ctrl+h</span>: Previous page in history, like back button on other browsers</li>
  96. <li><span class="code">Ctrl+r</span>: Refresh/reload.</li>
  97. <li><span class="code">Ctrl+-</span>: Zoom out a little</li>
  98. <li><span class="code">Shift+Ctrl++</span>: Zoom in a little</li>
  99. <li><span class="code">Shift+Ctrl+q</span>: Normal zoom</li>
  100. </ul>
  101. <h2>Get Surf Running First!!!</h2>
  102. <p>Tabbed works well. I promise. You can have all the tabs you want in Surf. Tabs won't be a problem.</p>
  103. <p>But for your own sanity, get Surf running first, learn how to use it, and if you're configuring it, configure it completely. You don't need the distractions of configuring/compiling Tabbed while learning Surf. While you're learning and setting up Surf, please remember there's no shame in running multiple copies of Surf, each tuned to a different website, and using your window manager's Ctrl+Tab to move between them. Soon enough you'll install, set up and use Tabbed to zip between tabs at the speed of light.</p>
  104. <h1 id="surfpkgmgr">Installing Surf With a Package Manager</h1>
  105. <p>Try installing Surf with a package manager. It might suit your needs, and if it does, that will save you a lot of work, because Surf has a lot more dependencies than you might first suspect, and lack of some of those dependencies could cause a runtime mistake (not even error, just malfunction) rather than failure to compile. So just use your package manager's search facility to find the package containing Surf, and use your standard package manager install command to install it. Then run Surf as follows:</p>
  106. <pre class="code">surf -p</pre>
  107. <p>Your next step is to operate Surf with its <a href="#surfhotkeys">hotkeys</a>.</p>
  108. <h1 id="surfhotkeys">Surf Hotkeys</h1>
  109. <p>To kill a single instance of Surf (not run with Tabbed), just use the Window Manager Close Window Command. Beyond that, the following comprise the most widely used Surf hotkeys:</p>
  110. <ul>
  111. <li><span class="code">Ctrl+g</span>: Go to URL (field on screen's upper left (not the browser window) opens for you to type)</li>
  112. <li><span class="code">Ctrl+p</span>: Go to URL in cut and paste clipboard</li>
  113. <li><span class="code">Ctrl+y</span>: Put current website URL into cut and paste clipboard</li>
  114. <li><span class="code">Ctrl+h</span>: Previous page in history, like back button on other browsers</li>
  115. <li><span class="code">Ctrl+l</span>: Undo the last Ctrl+h (go later in history)</li>
  116. <li><span class="code">Ctrl+r</span>: Refresh/reload from cache.</li>
  117. <li><span class="code">Ctrl+Shift+r</span>: Refresh/reload <em>without</em> cache</li>
  118. <li><span class="code">Ctrl+-</span>: Zoom out a little</li>
  119. <li><span class="code">Shift+Ctrl++</span>: Zoom in a little</li>
  120. <li><span class="code">Shift+Ctrl+q</span>: Normal zoom, and note that this might not be the zoom the browser opened with, if the browser was set to open with a non-normal zoom.</li>
  121. <li><span class="code">Ctrl+o</span>: Toggle "view source"</li>
  122. <li><span class="code">Ctrl+j</span>: Down a little</li>
  123. <li><span class="code">Ctrl+k</span>: Up a little</li>
  124. <li><span class="code">Ctrl+Space</span>: Down a lot</li>
  125. <li><span class="code">Ctrl+b</span>: Up a lot</li>
  126. <li><span class="code">Ctrl+i</span>: Scroll left a little</li>
  127. <li><span class="code">Ctrl+u</span>: Scroll right a little</li>
  128. <li><span class="code">F11</span>: Toggle fullscreen</li>
  129. <li><span class="code">Shift+Ctrl+b</span>: Toggle scrollbars</li>
  130. <li><span class="code">Shift+Ctrl+g</span>: Toggle geolocation</li>
  131. </ul>
  132. <h1 id="keyboardonly">Keyboard-Only Surf Usage</h1>
  133. <p>Surf is built more for keyboard use than for the mouse. There's no back button to click. There's no URL field to click and paste into. The person wanting to use a mouse would be much better off with Midori than with the standard default Surf. But if you like productivity, you like the keyboard, and for those who like the keyboard, Surf offers a wealth of keyboard techniques.</p>
  134. <h2 id="kbdlinks">Following Links From the Keyboard</h2>
  135. <p>Surf offers two very different ways to follow links from the keyboard. One way, link hints, is discussed in its <a href="#linkhints">own section</a> later in this document. The other way, using the arrow keys and Enter key, is described in the next couple paragraphs.</p>
  136. <p>The trick is to scroll with Ctrl+j or Ctrl+k till the link you want is approximately on the top or bottom of the viewing area, then use up arrow, down arrow, left and right to move the very thin dashed line to the link you want. Once the link is so surrounded, press Enter and Surf will download the page pointed to by that link. This isn't perfect. The thin dashed line is not visible at a glance: You need to look carefully. And it works only on text links. But in a great many cases, it gets the job done, especially for those with great visual acuity. And remember, you can always get <a href="#linkhints">link hints</a> running..</p>
  137. <h2 id="kbdbackbutton">Keyboard Back Button</h2>
  138. <p>Another productivity enhancer would be some sort of mouse-based "back button", so if you already have the mouse in your right hand, you can quickly use your left hand to tap a left-keyboard key. I personally use the Grave accent (<span class="code">'`'</span>). F2 (<span class="code">GDK_F2</span>) are both excellent for moving to the previous web page. As shipped, Surf already gives you Ctrl+Shift+l for this purpose, but that requires you to drop and later re-grab your mouse. With the Grave Accent, your right hand stays right on the mouse. The grave accent is incredibly easy to hit with the left hand, but it prevents ever typing a grave accent into a text entry field. F2 is harder to hit quickly (and without too much looking), but it's unlikely to conflict with any other situation. F1 is used for "help" in too many places, and Esc has too many other usages to make it practical.</p>
  139. <p>To do this, within <span class="code">config.h</span>, copy the original Ctrl+r hotkey line, and change the copy to either the Grave accent of F2. This document later features a section on <a href="#modsurf">modifying the source and recompiling</a>. </p>
  140. <h1 id="linkhints">Link Hints</h1>
  141. <p>No Surf feature is murkier, more poorly documented, and more argued about on the Internet than Link Hints. After reading and following the advice in this section, Link Hints will work perfectly for you every time.</p>
  142. <h2>The Controversy</h2>
  143. <p>Some folks say Link Hints works. Others say it doesn't work. Still others say it works on some websites and not others. The latter is the accurate assertion, as this section will later demonstrate. But first, the following is an example of how crazy arguments about whether it works or not can get:</p>
  144. <p>
  145. <a target="_blank" href="https://www.mail-archive.com/search?l=dev@suckless.org&amp;q=subject:%22Re%3A+%5Bdev%5D+%5Bsurf%5D+script.js%22&amp;o=newest&amp;f=1">https://www.mail-archive.com/search?l=dev@suckless.org&amp;q=subject:%22Re%3A+%5Bdev%5D+%5Bsurf%5D+script.js%22&amp;o=newest&amp;f=1</a></p>
  146. <p>There are other web pages with similar back-and-forth arguments, but they're hard to find because Surf is a common word and the Surf browser isn't used by many people. Meanwhile, Suckless Tools' official Link Hints page gives no indication that there's any problem at all:</p>
  147. <p><a href="http://surf.suckless.org/files/link_hints">http://surf.suckless.org/files/link_hints</a></p>
  148. <p>The section you're now reading settles this once and for all, by giving you a web page <a href="http://troubleshooters.com/simple_page.html">http://troubleshooters.com/simple_page.html</a> that doesn't work with Suckless Tools' official Link Hints Javascript code, and giving you a 12 line Javascript addition that causes all web pages, including <a href="http://troubleshooters.com/simple_page.html">http://troubleshooters.com/simple_page.html</a>, to work with Link Hints.</p>
  149. <h2>What are Link Hints</h2>
  150. <p>Link Hints are numbers that appear beside every link, after you press Ctrl+Shift+f. When you keyboard-input the number corresponding to a link, the web page that link points to is pulled up in a new browser, or if you're using Tabbed, a new tab. This means you can do all link work from the keyboard: A powerful productivity advantage once you get used to it. For the Surf browser, Link Hints are implemented in Javascript you copy into <span class="code">~/.surf/script.js</span>.</p>
  151. <h2>First Step: Install Link Hints the Suckless Way</h2>
  152. <p>Before doing anything else, back up your existing <span class="code">~/.surf/script.js</span>, if you have one. This procedure could mess it up, so be ready to put it back.</p>
  153. <p>The people at Suckless Tools have already written (almost) all the Javascript for you. First, navigate to <a href="http://surf.suckless.org/files/link_hints">http://surf.suckless.org/files/link_hints</a>. Go down to the section titled "Code". That section contains nothing but the Javascript code to implement Link Hints. Copy that entire block of code to the clipboard.</p>
  154. <p> In <span class="code">~/.surf/script.js</span>, put about 10 blank lines at the bottom, and below those blank lines , then paste the code you copied below the 10 blank lines, and theoretically you now have Link Hints. Test your new Link Hints on this web page by running the following command at the command prompt:</p>
  155. <pre class="code">surf -p http://troubleshooters.com/linux/surf.htm</pre>
  156. <p>This web page appears in a new browser. Now press Ctrl+Shift+f and notice that each link (there are several at the top of this web page) gets highlighted and acquires a number. Type in the number for one of the links and notice a new browser appears with that link's web page. You've proven that Surf's Link Hints work!</p>
  157. <p>On&#160;&#160;&#160;&#160;this&#160;&#160;&#160;&#160;web&#160;&#160;&#160;&#160;page.</p>
  158. <p>Now do the same thing, but with a very simple web page:</p>
  159. <pre class="code">surf -p http://troubleshooters.com/simple_page.html</pre>
  160. <p>On this simple web page, press Ctrl+Shift+f, and note that nothing happens. This is discouraging. This is what has created all the arguments, misunderstandings, and storming off the field on the Internet. The Link Hints given by Suckless Tools works for some web pages, and not for others. In fact, Suckless Tools' code works for any page that already has at least one CSS stylesheet, and fails on any web page not containing a CSS stylesheet. Suckless Tools' Javascript inserts CSS rules in Stylesheet 0, whether or not there is a Stylesheet 0, and many simple web pages have no CSS, so they have no Stylesheet 0.</p>
  161. <p>To see the exact location where the existence of at least one stylesheet is assumed and acted upon, see the first lines in functions <span class="code">setHintRules()</span> and <span class="code">deleteHintRules()</span>.</p>
  162. <h2>Second Step: Add Javascript to guarantee a stylesheet</h2>
  163. <p>So I created some Javascript that adds a Stylesheet if there are no stylesheets. Here's my Javascript:</p>
  164. <pre class="code">
  165. function guarantee_stylesheet(){
  166. var thehead = document.getElementsByTagName('head')[0];
  167. if (document.getElementsByTagName('style').length &lt; 1){
  168. var thesty = document.createElement('style');
  169. thesty.innerHTML = thesty.innerHTML + ' div#diag_kludge{color: #0099ff;} ';
  170. thesty.innerHTML = thesty.innerHTML + ' div#diag_kludge{background-color: #660000;} ';
  171. thehead.appendChild(thesty);
  172. divv = document.getElementById('diag_kludge');
  173. titl = headd.getElementsByTagName('title')[0];
  174. }
  175. }
  176. window.addEventListener('load', guarantee_stylesheet, false);
  177. </pre>
  178. <p>So, to guarantee Link Hints on all web pages, make ten blank lines below the current bottom of your <span class="code">~/.surf/script.js</span> file, and copy and paste the preceding code below the ten new blank lines, and save. Now test on a simple page:</p>
  179. <pre class="code">surf -p http://troubleshooters.com/simple_page.html</pre>
  180. <p>Press Ctrl+Shift+f and make sure the preceding page's one link is numbered, and that when you enter the number of that link, a new instance of Surf (or a new tab) appears with Troubleshooters.Com's home page. Troubleshoot as necessary, noticing that for debugging purposes, the preceding website actually has a <span class="code">div</span> with <span class="code">id</span> <span class="code">diag_kludge</span>. Make sure Link Hints still work with more complicated pages.</p>
  181. <h2>Hotkey for following links directly</h2>
  182. <p>Ctrl+Shift+f follows a link into a new tab. Sometimes that's what you want, but often it isn't. Pressing Ctrl+Shift+f to follow a series of links leaves you with too many tabs, perhaps dozens. Usually, what you want is to follow the link into its web page <em>in the current tab</em>.</p>
  183. <p>The Link Hints javascript code you copied actually offers such a hotkey: Ctrl+f. Unfortunately, Ctrl+f is already the hotkey for Find in Surf, and it's an excellent hotkey for that: Both mnemonic and commonly used. So you have to change Ctrl+f. I changed it to Ctrl+w just for ergonomic reasons. Change it to any other key combo you want that has no other meaning in Surf or Tabbed, but change it to something, because it's very necessary.</p>
  184. <h2>What You've Accomplished</h2>
  185. <p>What you just did was, in a paraphrase of Joe Biden, a Big Fantastic Deal! With the addition of surefire keyboard driven Link Hits, use of Surf exclusively through keyboard interaction becomes not only possible but easy and productive.</p>
  186. <h2>Link Hints Rules of the Road</h2>
  187. <p>Scroll then hint, not vice versa! If you scroll after Link Hinting, you'll very likely encounter unnumbered links. But if you scroll to the link you want (quite easy from the keyboard) and then press Ctrl+Shift+f, all links visible on the current screen are visible, and you can enter the desired number.</p>
  188. <p>Ctrl+Shift+f is a toggle! If you're anything like me, your first inclination when trying to turn off Link Hints will be to press the Escape key, but this doesn't work. Turn Link Hints off the same way you turned them off: With Ctrl+Shift+f.</p>
  189. <h2>Left as Exercises For the Reader</h2>
  190. <p>It took me a looooong time to identify the key distinction between websites that did and didn't work with Suckless Tools' Link Hint code (pre-existence of a stylesheet), and because I'm not the world's greatest Javascript guy and Surf isn't the greatest Javascript development environment, a long time to create the workaround. So I stopped before making Link Hints perfect. You can continue the work, and if you find how to improve it, please <a href="http://troubleshooters.com/email_steve_litt.htm">email me</a>.</p>
  191. <ol>
  192. <li><a href="#h3_includefiles">Include files within <span class="code">~/.surf/script.js</span></a></li>
  193. <li><a href="#h3_translinkhints">Transparent Link Hint highlighting</a></li>
  194. <li><a href="#h3_curbrows">Option to make followed link appear on current browser</a></li>
  195. </ol>
  196. <h3 id="h3_includefiles">Include files within <span class="code">~/.surf/script.js</span></h3>
  197. <p>By the time you add both Suckless Tools' Link Hints javascript and my guaranteed stylesheet addition, <span class="code">~/.surf/script.js</span> is a mess. If you've added in your own Javascript, <span class="code">~/.surf/script.js</span> becomes very hard to maintain. It would be nice if <span class="code">~/.surf/scrpt.js</span> looked more like the following:</p>
  198. <pre class="code">
  199. document.write('&lt;script src=".surf/surefire.js" type="text/javascript"&gt;&lt;/script&gt;');
  200. document.write('&lt;script src=".surf/linkhinting.js" type="text/javascript"&gt;&lt;/script&gt;');
  201. </pre>
  202. <p>However, I tried the preceding, and it didn't facilitate Link Hints when pressing Ctrl+Shift+f, so I went on to other things and left this as an exercise for the reader.</p>
  203. <h3 id="h3_translinkhints">Transparent Link Hint highlighting</h3>
  204. <p>The current link highlighting often obstructs the text of the link. So you need to toggle Link Hints off, memorize the relevant links, and then toggle Link Hints on. Not good for productivity.</p>
  205. <p>Fixing this would require going into Suckless Tools' javascript code and changing the CSS. Either the original colors must be evaluated to change the text color to a contrast of the new background color, or perhaps leave foreground and background alone except make the text blink. Yeah, this is the first time I've ever recommended blink, but it might make sense in this case.</p>
  206. <p>I can use Link Hints in its current form, just toggling Link Hinting to memorize the relevant link texts. So I leave a more readable solution as an exercise to the reader.</p>
  207. <h3 id="h3_curbrows">Option to make followed link appear on current browser</h3>
  208. <p>Right now, following a link with Link Hints always brings up a new browser or tab, whereas you might desire following the link in the current browser or tab. Each has its own advantages and best situations. I leave it as an exercise for the reader to implement this as an option.</p>
  209. <h3>Email me with solutions</h3>
  210. <p>If you manage to implement solutions for any of these suggested improvements, please <a href="http://troubleshooters.com/email_steve_litt.htm">email me</a>.</p>
  211. <h1 id="modsurf">Modifying Surf</h1>
  212. <p>If you can use Surf as it comes from your package manager, by all means do that, because the alternative is downloading and compiling it. Almost all configuration requires recompilation. And compiling Surf requires many more dependencies than you might imagine.</p>
  213. <p>That being said, a few added hotkeys makes Surf much more productive. Also, most packagers assume the world has 20/20 vision, so you might have no choice but to modify it so you can see it. Especially obnoxious is the tendency to make dmenu entries (Surf uses dmenu for all input) tiny-fonted midgray on darkgray. I mean really, couldn't you have set it up white on black or bright green or light yellow on black? Who would it have offended? But noooooo.</p>
  214. <p>So in many cases, you have no choice to compile Surf. Don't worry, it's quite doable.</p>
  215. <ol>
  216. <li><a href="#h2_downinst">Download and install the source</a></li>
  217. <li><a href="#h2_investigate">Investigate the source files</a></li>
  218. <li><a href="#h2_usual_supects">Package install the usual suspects <ul>
  219. <li><a href="#h3_gtkplus">gtk+ header files</a></li>
  220. <li><a href="#h3_webkitgtkplus">all webkit+gtk+ header files</a></li>
  221. <li><a href="#h3_pkg_config">pkg-config</a></li>
  222. <li><a href="#h3_dmenu">dmenu (available at <a href="http://suckless.org">suckless.org</a> if your distro has no package for it)</a></li>
  223. <li><a href="#h3_gdb">gdb and gdb-debug (helps prevent intermittent crashes)</a></li>
  224. </ul></a></li>
  225. <li><a href="#h2_compile_script">Write a compile/run shellscript</a></li>
  226. <li><a href="#h2_keep_compiling">Keep compiling till it works</a></li>
  227. <li><a href="#h2_configure_surf">Configure Surf</a></li>
  228. <li><a href="#h2_make_install">Make install</a></li>
  229. </ol>
  230. <h2 id="h2_downinst">Download and install the source</h2>
  231. <p>Download the tarball (link at bottom of <a href="http://surf.suckless.org/">http://surf.suckless.org/</a>. Untar the tarball into a directory owned by a non-root user. You'll see several files, including a README file.</p>
  232. <h2 id="h2_investigate">Investigate the source files</h2>
  233. <p>Start by reading <span class="code">README</span>, <span class="code">config.mk</span> and <span class="code">config.def.h</span>. Don't change any of them unless you're using BSD or a very bizarre Linux distribution, and not even then. The first time you compile, <span class="code">config.dev.h</span> and <span class="code">config.mk</span> are consulted to create <span class="code">config.h</span>, which in all but the most abnormal cases should be the only file you modify. </p>
  234. <p>As you read <span class="code">config.dev.h</span>, which as you remember you do not modify, you'll see all sorts of boolean properties, a few functions and macros, and down toward the bottom a bunch of hotkeys and a few mouseclick mappings to functions. It's these hotkeys and perhaps mouseclicks that you'll spend the most time with.</p>
  235. <p>Search for the string <span class="code">dmenu</span>, which occurs inside a macro called <span class="code">SETPROP</span>. If, when you press Ctrl+g or Ctrl+f, the text in the input area that opens at the top left of the screen isn't readable enough, you'll later be changing that by adding arguments to <span class="code">dmenu</span>, as later detailed in the <a href="#surfconfigdetails">Surf Configuration Details</a> section.</p>
  236. <h2 id="h2_usual_supects">Package install the usual suspects</h2>
  237. <p>The packages you <em>know</em> must be installed to make Surf work are the following:</p>
  238. <ul>
  239. <li><a href="#h3_gtkplus">gtk+ header files</a></li>
  240. <li><a href="#h3_webkitgtkplus">all webkit+gtk+ header files</a></li>
  241. <li><a href="#h3_pkg_config">pkg-config</a></li>
  242. <li><a href="#h3_dmenu">dmenu (available at <a href="http://suckless.org">suckless.org</a>)</a></li>
  243. <li><a href="#h3_gdb">gdb and gdb-debug (helps prevent intermittent crashes)</a></li>
  244. </ul>
  245. <h3 id="h3_gtkplus">gtk+ header files</h3>
  246. <p>Surf uses GTK+, so you need all the GTK+ header files, which normally aren't installed. Search your package manager for all packages with string "gtk+" and also containing "devel", for your architecture.</p>
  247. <h3 id="h3_webkitgtkplus">all webkit+gtk+ header files</h3>
  248. <p>What a mess. There are Webkit + GTK packages, and Webkit2 + GTK, and Webkit + GTK2, and Webkit2 + GTK2. My experience is that if it has the strings "webkit", "gtk" and "devel", and is a package for your architecture (64 bit or 32 bit), you're best off to install it now. If you happen to install an extra one, that's a lot easier than not installing the right one(s) and having to troubleshoot. If really needed, you can delete what you believe to be the extra one(s), one at a time, after it's compiling, and if it continues to compile, I guess it was extra. But if you want to get Surf compiled before New Years, install them all at first.</p>
  249. <h3 id="h3_pkg_config">pkg-config</h3>
  250. <p>This is used by the Surf make file to configure certain packages. Even though this package is maintained by Freedesktop.Org, it has almost no dependencies.
  251. </p>
  252. <h3 id="h3_dmenu">dmenu (available at <a href="http://suckless.org">suckless.org</a>)</h3>
  253. <p>Surf compiles without dmenu, but you won't be able to input a URL or search string without it. Install dmenu.</p>
  254. <h3 id="h3_gdb">gdb and gdb-debug (helps prevent intermittent crashes)</h3>
  255. <p>gdb is the Gnu Debugger. Surf runs perfectly without it. Most of the time. But occasionally a challenging website makes it error out with a message about not finding gdb. If you install gdb and gdb-debug, this particular error can't happen.</p>
  256. <h2 id="h2_compile_script">Write a compile/run shellscript</h2>
  257. <p>While compiling and configuring Surf, you'll do many instances of make plus run. And you sure don't want to log in as root and do a make&#160;install every time. So create the following shellscript to make and run, in the current directory, as you:</p>
  258. <pre class="code">
  259. #!/bin/sh
  260. cd ~/compiles/surf-0.7
  261. rm -f ./surf
  262. make clean
  263. make
  264. ./surf -p ~/mybookmarks.html
  265. </pre>
  266. <p>The preceding script assumes your source files are in <span class="code">~/compiles/surf-0.7</span>, which is the current version on 3/9/2017. If your Surf version is different, modify line 2 accordingly. I called my shellscript <span class="code">jj</span>, because it's very easy to type <span class="code">./jj</span> over and over again.</p>
  267. <h2 id="h2_keep_compiling">Keep compiling till it works</h2>
  268. <p>Even if you followed every instruction so far in this document, I'm betting your first compile will fail. Something always goes wrong. So just read error messages and keep fixing the problem accordingly. The problem is usually a package that hasn't been installed yet.</p>
  269. <p>After it compiles, it probably won't work right, so you'll need to keep tweaking and compiling it till it does. Just keep compiling again and again until it's perfect. Each compile takes about 3 seconds, so it's no big deal.</p>
  270. <h2 id="h2_configure_surf">Configure Surf</h2>
  271. <p>Even when it works right, you'll probably want to add some custom hotkeys, and maybe, if your vision is less than that of an eagle, add size and contrast to some fonts, and then recompile. Keep on until it's perfect.</p>
  272. <h2 id="h2_make_install">Make install</h2>
  273. <p>When surf is exactly how you want it, it's time to install it and its man pages in the standard way, which is in <span class="code">/usr/local/bin</span> and <span class="code">/usr/local/man</span>. So perform the following command to do this:</p>
  274. <pre class="code">su -c "make install"</pre>
  275. <p>Or, if you have one of those distros that depends on <span class="code">sudo</span>, perform the following:</p>
  276. <pre class="code">sudo make install</pre>
  277. <p>After you type in the password, Surf will be installed. By the way, Surf has an "uninstall" option for its make, if you ever need to use that.</p>
  278. <h1 id="surfconfigdetails">Surf Configuration Details</h1>
  279. <p>This section details how you can configure your Surf program to your exact needs. All the work described in this section is performed by editing the <span class="code">config.h</span> file. This section describes the setting of several simple details, and then goes heavily into setting hotkeys, and setting the font size of the dmenu-driven URL input field, via modifications to the dmenu part of the SETPROP() macro.</p>
  280. <p>Open up the <span class="code">config.h</span> file and browse through it. At the top is the user agent string, which is the browser which Surf is masquerading as. This is necessary because sites created with Surf in mind are rare indeed. Even sites created to be browser-agnostic (like the one you're now reading), are fairly rare. After the user agent string comes some strings representing files and directories used by Surf. Then come some booleans affecting how Surf looks and behaves.</p>
  281. <p>Then you come to the first things you're likely to modify: The default font and zoom level. If Surf seems to render fonts and/or images too small for your eyesight, try cranking up the zoomlevel a little bit. If that doesn't work, maybe crank up the default font size just a smidge. Be careful though, if you use big numbers like a 1.8 zoom level or a 22 point font, many sites will render into what looks like a junk heap, so enlarge only as needed.</p>
  282. <p>Next you come to a bunch of mostly booleans determining how webkit acts. For the most part, you'll probably want to leave these alone. Next you come to the SETPROP() macro, which has its own subsection within this section.</p>
  283. <h2 id="hotkeys">Hotkeys</h2>
  284. <p>Skip on down to the following line:</p>
  285. <pre class="code">#define MODKEY GDK_CONTROL_MASK</pre>
  286. <p>MODKEY is Surf's foundational modifier key. A modifier key is a keyboard key that modifies rather than printing, such as Ctrl, Alt, or the Windows key. The makers of Surf believed that Ctrl was the best choice for MODKEY, and for the most part I concur, but if you're not using the Windows key for anything else and want to use it for Surf hotkeys, you can do that by changing the preceding line to the following one:</p>
  287. <pre class="code">#define MODKEY GDK_SUPER_MASK</pre>
  288. <p>Below the preceding line of code is a comment warning you "If you use anything else but MODKEY and GDK_SHIFT_MASK, don't forget to edit the CLEANMASK() macro." That warning applies to the modifier mask of a hotkey record.</p>
  289. <p>Below the warning is the declaration for an array called <span class="code">keys[]</span>, which is an array of a typedef called <span class="code">Key</span>. The following is the definition for <span class="code">Key</span>, as coded in <span class="code">surf.c</span>:</p>
  290. <pre class="code">
  291. typedef struct {
  292. guint mod;
  293. guint keyval;
  294. void (*func)(Client *c, const Arg *arg);
  295. const Arg arg;
  296. } Key;
  297. </pre>
  298. <p>In other words, each <span class="code">Key</span> element in the <span class="code">keys[]</span> array is a struct consisting of:</p>
  299. <ol>
  300. <li>Modifier mask, which is the value obtained when OR'ing all modifier keys pushed to form this hotkey. In other words, to form Shift+Ctrl+r, the modifier mask (<span class="code">mod</span>) would be <span class="code">MODKEY&#160;|&#160;GDK_SUPER_MASK</span>, and the letter (<span class="code">keyval</span>) would be <span class="code">'r'</span>.</li>
  301. <li>The keyboard key (key that inserts something in the output). In other words, to form Shift+Ctrl+r, the modifier mask (<span class="code">mod</span>) would be <span class="code">MODKEY&#160;|&#160;GDK_SUPER_MASK</span>, and the letter (<span class="code">keyval</span>) would be <span class="code">'r'</span>, or for portability's sake the letter would be <span class="code">GDK_r</span>.</li>
  302. <li>A callback function that gets performed when this hotkey is pressed.</li>
  303. <li>A generic argument that can be a an int, a boolean, or a pointer to void. How this argument is used depends on the callback.</li>
  304. </ol>
  305. <p>To summarize the preceding several paragraphs, the definition of a hotkey is an element in the <span class="code">keys[]</span> array consisting of a struct with elements modifier keys, regular key, callback function, and argument. This means you can make your own hotkeys by copying other hotkeys and changing one or more of the four elements. You need to know the GTK symbols for the keyboard keys, and this info can currently (3/2017) be found at <a href="https://www.rpi.edu/dept/acm/packages/gtk/1.2.10/gtk+-1.2.10/gdk/gdkkeysyms.h">https://www.rpi.edu/dept/acm/packages/gtk/1.2.10/gtk+-1.2.10/gdk/gdkkeysyms.h</a>. You'll probably have a local copy of <span class="code">gdkkeysyms.h</span>, findable with the following command:</p>
  306. <pre class="code">find /usr/include | grep gdkkeysyms.h</pre>
  307. <p>Here are some hotkeys I added:</p>
  308. <ol>
  309. <li><span class="code">{ 0 , GDK_F2, navigate, { .i = -1 } },</span></li>
  310. <li><span class="code">{ 0 , GDK_grave, navigate, { .i = -1 } },</span></li>
  311. <li><span class="code">{ 0 , GDK_F5, reload, { .b = TRUE } },</span></li>
  312. <li><span class="code">{ 0 , GDK_F6, spawn, SETPROP("_SURF_URI", "_SURF_GO") },</span></li>
  313. <li><span class="code">{ MODKEY, GDK_e, loaduri, { .v = HOMEPAGE } },</span></li>
  314. </ol>
  315. <p>In the preceding, #1 goes back to the last viewed page (like a back button) when the user presses F2. #2 does the same thing when the user presses the grave accent (<span class="code">`</span>. Both of these aid the mouse user in doing the back function without dropping the mouse and assuming a full home key typing position. #3 gives Surf the same reload hotkey as Firefox, Chromium, Palemoon and the like. #4 partially replicates the F6 action of major browsers and brings up the URL field. #5 needs a discussion of its own...</p>
  316. <h3>Creating a home-page hotkey</h3>
  317. <p>Theoretically a <span class="code">tabbed&#160;surf</span> session should go to the last argument given to the <span class="code">surf</span> command, as should each newly-invoked tab. Sometimes, when you use the <span class="code">surf-open.sh</span> script from a browser, email client or irc client that doesn't happen just right. Also, sometimes on an already navigated tab you just want to go right to your home page. So you need to define a home page and key combo to make that happen. The key combo is easy: Just place the following line toward the bottom of the rest of your hotkey definitions in Surf's <span class="code">config.h</span>:</p>
  318. <pre class="code">{ MODKEY, GDK_z, loaduri, { .v = HOMEPAGE}},</pre>
  319. <p>The only remaining task is that constant <span class="code">HOMEPAGE</span> is undefined. No problem. Go up in <span class="code">config.h</span>, and just before the definition of <span class="code">SETPROP</span>, insert the following three lines, surrounded on top and on the bottom with blank lines:</p>
  320. <pre class="code">
  321. /* Steve Litt additions */
  322. #define HOMEPAGE "http://192.168.100.2/littlinks.html"
  323. /* End of Steve Litt additions */
  324. </pre>
  325. <p>Obviously, you'll change the string assigned to <span class="code">HOMEPAGE</span> to the URL of whatever you'd like as your home page.</p>
  326. <p>One more task remains: You really need the go-to-homepage functionality accessible via the mouse too. So, at the bottom of all the mouse click definitions at the bottom of <span class="code">config.h</span>, insert the following:</p>
  327. <pre class="code"> { ClkAny, MODKEY, 1, loaduri, { .v = HOMEPAGE } },
  328. </pre>
  329. <p>The preceding makes left Ctrl+leftclick go to the home page. Obviously, you'll change the string assigned to <span class="code">HOMEPAGE</span> to the URL of whatever you'd like as your home page. The following shows it assigned to <span class="code">http://192.168.100.2/littlinks.html</span>. That page is a hierarchy of links that I keep up. Obviously, you'll assign it to the home page of your choice. Insert the following code, surrounded on both ends by a blank line, modified to represent your desired web page, right above the definition of <span class="code">SETPROP</span>:</p>
  330. <pre class="code">
  331. /* Steve Litt additions */
  332. #define HOMEPAGE "http://192.168.100.2/littlinks.html"
  333. /* End of Steve Litt additions */
  334. </pre>
  335. <p>Now, every time you press Ctrl and then left click on the browser, your desired home page is displayed.</p>
  336. <h2 id="pluginornot">To Plugin, or Not to Plugin?</h2>
  337. <p>There are certain corner cases, involving variables such as distro, build, webkit build, perhaps which plugins are installed, and which website you're looking at, that can cause Surf to abort with no useful message either in the Surf window or in the terminal from which Surf was invoked. Judging from the fact that Midori, Xombrero and Luakit exhibit this same intermittent problem but Chromium, Palemoon and Firefox do not, I suspect it's a Webkit thing, and only on certain distros (I'm seeing it on Void, but my friends with Devuan don't see it). Luckily, Surf gives you an easy way to work around this corner case problem.</p>
  338. <p>It turns out that if you turn off plugins in Surf, you turn off this corner case problem. This is why, throughout this document, I've recommended using the <span class="code">-p</span> option to Surf: <span class="code">-p</span> turns off plugins. If you find it hard to remember to use this option in every shellscript and every command you type, you have the alternative of turning off plugins in the <span class="code">surf</span> command itself, by making a small change within <span class="code">config.h</span>. Find the following line:</p>
  339. <pre class="code">static Bool enableplugins = TRUE;</pre>
  340. <p>Change the <span class="code">TRUE</span> to <span class="code">FALSE</span>, recompile and reinstall. Now, when you run the <span class="code">surf</span> command, Surf operates with no plugins.</p>
  341. <h2 id="setpropdmenu">SETPROP(), dmenu and URL Font</h2>
  342. <p>Why, oh why do developers assume the user has 20/20 vision?</p>
  343. <p>Surf uses dmenu to acquire URLs and search screens from the user, and unfortunately, dmenu ships from Suckless Tools with a rather small and thin 10 point non-bold monospace font. It ships with non-contrasty colors: Normal video foreground is #bbbbbb (semi-light gray) on #222222 (very dark gray). The selected video is also less than ideal at #eeeeee on #005577. If you fall short of 20/20, it's hard to see what you're typing or what the default is.</p>
  344. <p>My dmenu comes from the package manager, so I can't change the colors by dmenu compilation. But I can sure change them by dmenu arguments, and that's what I do in the <span class="code">SETPROP()</span> macro. I take the following line:</p>
  345. <pre class="code"> "| xargs -0 printf %b | dmenu`\" &amp;&amp;" \</pre>
  346. <p>I strongarmed the colors to high contrast by adding arguments to the <span class="code">dmenu</span> call:</p>
  347. <pre class="code"> "| xargs -0 printf %b | dmenu -nf '#ccffff' -nb '#000000' -sf '#000000' -sb '#ffffff'`\" &amp;&amp;" \</pre>
  348. <p>Notice the singlequotes around the argument values. Don't use doublequotes. Don't go entirely without quotes. Use single quotes because that's what works. Now, about the meaning of these options:</p>
  349. <ul>
  350. <li><span class="code">-nf</span>&#160;&#160;&#160;Normal foreground</li>
  351. <li><span class="code">-nb</span>&#160;&#160;&#160;Normal background</li>
  352. <li><span class="code">-sf</span>&#160;&#160;&#160;Selected (highlighted) forground</li>
  353. <li><span class="code">-sb</span>&#160;&#160;&#160;Selected (highlighted) background</li>
  354. </ul>
  355. <p>You might decide to use one other dmenu option: <span class="code">-fn</span>, the font. It's normally not a good idea to enlarge fonts, but if increased contrast doesn't work, or the fonts are obviously microscopic, you might have to. Occasionally microscopic fonts are due to a delusional developer who thinks the world shares his 20/10 vision, but most of the time they occur due to a "no such font" situation. In these cases, you need to specify the font.</p>
  356. <p>Finding the designation of a workable font can be an exhausting trudge of trial and error through the lands of <span class="code">fonts.alias</span>, <span class="code">xfontsel</span>, and shortcut names like <span class="code">10x20</span>.</p>
  357. <p>Fortunately, there's a reliable designation that works with whatever fonts you happen to have installed on your computer. It consists of a family designation that is either "sans", "serif" or "monospace", followed optionally by one or more key/value pairs describing the font appearance. The following is a comically large example:</p>
  358. <pre class="code">echo Hello world | dmenu -fn monospace:size=24:weight=bold:slant=italic</pre>
  359. <p>In the preceding command, first notice the fact that <em>all</em> characters are lower class. Keep everything lowerclass in the <span class="code">-fn</span> specification. It's true that you can sometimes get away with uppercase letters in the values of some of the key/value pairs, but those cases aren't determinate or logical or easy to describe. Keeping everything lowercase keeps everything working. And remember, the font family designation must always be one of the following three:</p>
  360. <ul>
  361. <li>monospace</li>
  362. <li>sans</li>
  363. <li>serif</li>
  364. </ul>
  365. <p>The following is a practical line for the dmenu command within Surf:</p>
  366. <pre class="code">dmenu -nf '#ccffff' -nb '#000000' -sf '#000000' -sb '#ffffff' -fn 'sans:size=14:weight=bold'</pre>
  367. <p><a href="surf_dmenu_modified_cmd.txt">click here</a> to see the entire line.</p>
  368. <p>Referring to the preceding command, if you wanted to make it bold without changing the size, simply remove <span class="code">:size=14</span> from the string. In other words, remove one colon and the size specification. Making fonts bigger often causes geometric problems, but making fonts bold, which usually helps readability immensely, has very little downside.</p>
  369. <h1 id="installingtabbed">Installing Tabbed</h1>
  370. <div class="note">
  371. <p class="title">NOTE:</p>
  372. Before doing anything with the Tabbed program, make sure you've compiled Surf exactly how you want it, and you've installed Surf with its <span class="code">make&#160;install</span> compile command. Make sure also that, if there was also a package manager created Surf, that you have uninstalled it. When you work with Tabbed, you want to make sure it's working with the right version of Surf.
  373. </div>
  374. <p>Install the Tabbed package from your package manager. Now run each of the following commands:</p>
  375. <ol>
  376. <li><span class="code">tabbed surf -pe</span></li>
  377. <li><span class="code">tabbed -r2 surf -pe x troubleshooters.com</span></li>
  378. </ol>
  379. <p>The preceding are the two different ways to run Surf from Tabbed. The first way has no home page, so that every new tab is a blank web page. The second way opens every new tab to a specific web page: Most likely an HTML list of your favorite links. Each way has pros and cons.</p>
  380. <p>Method #2 is a big productivity boost if you have an excellent HTML links page maintained up to date. Method #1 enables you to use the Ctrl+T key combo to open a new tab and specify its URL in one step, and also, #1's command syntax is much easier to remember and more explainable. So choose one of the two methods and run Surf under Tabbed. A list of Tabbed hotkeys follows:</p>
  381. <ul>
  382. <li><span class="code">Shift+Ctrl+Enter</span>: New tab</li>
  383. <li><span class="code">Shift+Ctrl+l</span>: Next higher number tab</li>
  384. <li><span class="code">Shift+Ctrl+h</span>: Next lower number tab</li>
  385. <li><span class="code">Ctrl+Tab</span>: Toggle between last 2 tabs</li>
  386. <li><span class="code">Ctrl+1</span>: Switch to tab 1</li>
  387. <li><span class="code">Ctrl+2</span>: Switch to tab 2</li>
  388. <li><span class="code">Ctrl+3</span>: Switch to tab 3, etc.</li>
  389. <li><span class="code">Ctrl+q</span>: Close this tab</li>
  390. <li><span class="code">Ctrl+t</span>: Tab picklist</li>
  391. </ul>
  392. <p>Spend some time operating Surf through Tabbed. See how you like it. Notice that if you're running without a home page, when you use Ctrl+T, you can just type in your new URL and press Enter, and the new tab will show that URL's page. Make sure to use the Ctrl+T tab picklist several times, and decide whether its font and contrast are appropriate for you. If not, you'll need to modify Tabbed, a subject covered later in this document. Look at the thin black strip above the content and below the titlebar (if you have a titlebar) and note the font and contrast of writing on it. Is that writing legible enough not to slow you down? If not, you'll need to modfy Tabbed.</p>
  393. <p>There's a whole <a href="#modtabbed">section on modifying Tabbed</a>, but first let's look at the command used to run Surf under Tabbed...</p>
  394. <h1 id="cmdexpl">Explanation of Commands</h1>
  395. <p>The command to run Surf under Tabbed without a home page is as follows:</p>
  396. <pre class="code">tabbed surf -pe</pre>
  397. <p>In the preceding -p is necessary in order to prevent plugins. In some situations (such as my Void Linux installation), running Surf with plugins allowed sooner or later results in the dread Webkit "quick vanish" problem. The e in <span class="code">-pe</span> means "parent this Surf to the window ID after the <span class="code">e</span>. Of course, there's no window ID after the <span class="code">e</span>, so the plot thickens. The deal is, Tabbed places the window ID at the end of the entire command, so things work out. But if you try to add a home page using the following command, it gripes about not being able to find a web page with a long numeric URL:</p>
  398. <pre class="code">
  399. ###### THE FOLLOWING IS WRONG!!! ######
  400. tabbed surf -pe troubleshooters.com
  401. </pre>
  402. <p>The preceding throws an error resembling "Problem occurred while loading the URL http://134217731/". That number (and your number will be different and may change from time to time) is the window ID. The explanation is that the <span class="code">tabbed</span> command bolted the window ID at the end of the <span class="code">surf</span> command. Having the window ID at the end of the command causes failure because, when using the <span class="code">-e</span> option, <span class="code">surf</span> uses its very last argument as the website to look up, but Tabbed appends the window ID at the end.</p>
  403. <p>What you really need is the following:</p>
  404. <pre class="code">tabbed surf -pe &lt;windowID&gt; troubleshooters.com</pre>
  405. <p>But you can't do that because you don't know the window ID ahead of time. Right? Well, it turns out you <em>can</em> do that, though indirectly. Read the part of the Tabbed man page dealing with the <span class="code">-r</span> option...</p>
  406. <p>The <span class="code">-r</span> option specifies the number of the argument of the <em>surf</em> command to replace with the window number. Notice I said the number of the argument of the <em>surf</em> command, not the number of the argument of the Tabbed command. The reason the man page uses the word "command" instead of "surf" is that Tabbed works with several other programs to give them tabs. Just keep in mind that a Tabbed command generically looks like the following:</p>
  407. <pre class="code">tabbed &lt;tabbedoptions&gt; &lt;command&gt; &lt;command options&gt; </pre>
  408. <p>The <span class="code">-r</span> option for <span class="code">tabbed</span> refers to the argument of <span class="code">&lt;command&gt;</span></p>
  409. <p>Remember, what you need is the equivalent of:</p>
  410. <pre class="code">tabbed surf -pe &lt;windowID&gt; troubleshooters.com</pre>
  411. <p>To achieve that aim, do the following:</p>
  412. <pre class="code">tabbed -r 2 surf -pe x troubleshooters.com</pre>
  413. <p>The preceding puts the letter "x" as a placeholder for the window ID, and then uses the <span class="code">tabbed</span> <span class="code">-r</span> option to specify that Surf's arg 2 gets replaced with the window ID. Well, Surf's arg2 is the "x" placeholder. Try it: It works.</p>
  414. <h1 id="modtabbed">Modifying Tabbed</h1>
  415. <p>To modify Tabbed, you need to download its source tarball (.tgz) file, untar, modify its <span class="code">config.h</span>, and compile. Here's a good compile/run script to use until you get it just right:</p>
  416. <pre class="code">
  417. #!/bin/sh
  418. cd ~/compiles/tabbed-0.6
  419. rm -f ./tabbed
  420. make clean
  421. make
  422. ./tabbed -r2 surf -pe x
  423. </pre>
  424. <p>Repeatedly modify <span class="code">config.h</span> and run the preceding shellscript until Tabbed works just how you want, then perform the following:</p>
  425. <pre class="code">su -c "make install"</pre>
  426. <p>Or if you're on one of those distros that depends on <span class="code">sudo</span>,</p>
  427. <pre class="code">sudo make install</pre>
  428. <p>The preceding paragraphs covered the compile part of modifying Tabbed. Now for the questions "how" and "why?" From my perspective, the hotkeys of Tabbed are good and useful, so the only reason I'd want to modify the default is fonts and colors. Tabbed writes in two places:</p>
  429. <ul>
  430. <li>Dmenu tab picklist when you press Ctrl+T</li>
  431. <li>The tab strip on the browser</li>
  432. </ul>
  433. <p>If the dmenu picklist isn't readable enough for you, perform the same steps on it that you did when <a href="#setpropdmenu">the dmenu URL acquirer field with the SETPROP() macro</a>.</p>
  434. <p>I find Tabbed's as-shipped colors for the tab strip unfortunate. When seeing what tab you're on, or what tab you want to move to, the difference between current and other tabs must be obvious at a glance. As shipped from Suckless Tools, the current tab is #ffffff on #555555, and the non-current tabs at #cccccc on #222222. This is not glanceable, and in fact these two gray-on-grays aren't even easy to read, let alone glance. And the tiny font is reedy -- it would be much better if it were bold. I'm not going to tell you what colors to use, but if you want to gain the full utility of tabs, change the colors so the text is readable and it's obvious at a glance which tab is current. If you want to follow my advice and make the tabs font bold, perform the following:</p>
  435. <ul>
  436. <li>Change <span class="code">static const char font[] = "-*-*-medium-*-*-*-14-*-*-*-*-*-*-*";</span></li>
  437. <li>becomes <span class="code">static const char font[] = "-*-*-bold-*-*-*-14-*-*-*-*-*-*-*";</span></li>
  438. </ul>
  439. <h1 id="mouseprimary">Mouse-primary Surf Usage</h1>
  440. <p>As it ships from the factory, Surf is more mouse-friendly than you'd initially imagine. Obviously, you can click on links, just like any other browser. You can turn the mouse wheel to scroll a little, or you can drag the scrollbar to scroll a lot. Right clicking on a web page's background brings up a menu from which you can go back (like a backbutton), go forward, or reload the page. If your mouse has buttons 8 and 9, then button 8 is already configured to go back (like a backbutton) and button 9 is configured to go forward. If you're using Tabbed, the mouse wheel on the thin black horizontal tab menu cycles through your tabs. You can also left click on a specific tab in the tab menu to choose that tab. Middle-clicking on the text of a tab closes that tab. Here's a summary:</p>
  441. <ul>
  442. <li>LEFT click on LINK = go to that link</li>
  443. <li>LEFT click on TAB TEXT = go to that tab</li>
  444. <li>Ctrl + LEFT click on LINK = go to that link in a new browser outside of Tabbed</li>
  445. <li>CENTER click on LINK = go to that link in a new tab</li>
  446. <li>Ctrl + CENTER click on LINK = go to that link in a new browser outside of Tabbed</li>
  447. <li>CENTER click on TAB TEXT = close that tab</li>
  448. <li>BUTTON8 click in BROWSER = go backwards in history</li>
  449. <li>BUTTON9 click in BROWSER = go backwards in history</li>
  450. <li>WHEEL scroll in BROWSER = scroll the web page</li>
  451. <li>WHEEL scroll in TAB AREA = rotate through tabs</li>
  452. </ul>
  453. <p>About the only common browser functionalities not included in the preceding list are opening a new tab and acquiring a new URL (like Ctrl+g). You can add those functionalities if you want. Once you add them, the only thing you'll need the keyboard for is typing in a URL, and that's something that's never going to be done efficiently with a mouse.</p>
  454. <h2>Acquiring a New URL With the Center Mouse Button</h2>
  455. <p>In the Surf window itself, as opposed to the Tabbed strip, you want the mouse's center button to acquire a URL and display that page, exactly like Ctrl+g does. It seems easy enough to do within <span class="code">config.h</span>, by adding the following mouse button record at the bottom of all the other mouse button records defining the <span class="code">buttons[]</span> array:</p>
  456. <pre class="code">{ ClkDoc, 0, 2, spawn, SETPROP("_SURF_URI", "_SURF_GO") },</pre>
  457. <p>The <span class="code">ClkDoc</span> means "clicked anywhere on the document. It would override middle click of a link if it were above the line specifying middle click in a link, but because it's lower down in the <span class="code">buttons[]</span> array, and the array is looped through top to bottom, middle button on a link does what's specified for middle click on a link. When adding keystrokes and/or mouse strokes, always be careful about order, because both are read and executed in order.</p>
  458. <p>The good news is, the preceding addition enables the middle mouse button on an unpopulated area of the browser window to perform the "acquire URL and go there" functionality. The bad news is that unless you've already used Ctrl+g to do that on this particular window, it acquires the URL but doesn't go there, and if you're watching the stdout on the terminal from which you ran Surf, you'll see an error saying "xprop: error: Invalid window id format: _SURF_URI." So the user must do a per-tab intervention to make the middle mouse button acquire and go. That's inexcusable.</p>
  459. <p>Given that the window id format is wrong only before acquire and go have been used successfully, it seems likely to be a window id initialization problem. Looking at all the functions in <span class="code">surf.c</span>, just by name function <span class="code">updatewinid()</span> seemed likely to be involved. Searching all occurrences of <span class="code">updatewinid()</span> revealed that <span class="code">updatewinid()</span> is called from the <span class="code">kepress()</span> function, but not by its mouse counterpart, <span class="code">buttonrelease()</span>. Indeed, commenting out <span class="code">updatewinid()</span> within <span class="code">keypress()</span> created the exact same error on pressing Ctrl+g. The <span class="code">updatewinid()</span> function occurs just before the <span class="code">for</span> loop in <span class="code">keypress()</span>, so I put one just above the <span class="code">for</span> loop in <span class="code">buttonrelease()</span>, and <em>bang</em>, the problem went away.</p>
  460. <p>So to complete your installation of middle mouse button bringing up acquire and goto URL, place the following line immediately above the <span class="code">for</span> statement in function <span class="code">buttonrelease</span>:</p>
  461. <pre class="code"> updatewinid(c);</pre>
  462. <p>So, placing one line in <span class="code">config.h</span> and one in <span class="code">surf.c</span> adds the functionality.</p>
  463. <p>One more thing. I've never maintained this code, and I'm not as good a developer as the person who does, but I have a strong hunch that leaving out the <span class="code">updatewinid()</span> in function <span class="code">buttonrelease()</span> was an oversight, given the design resemblance of <span class="code">updatewinid()</span> to <span class="code">keypress()</span>. However, it's also possible that my insertion of the call to <span class="code">updatewinid()</span> could cause side effects, perhaps even a security flaw. You need to ask more knowledgeable people than me about that.</p>
  464. <h2>Making Ctrl+leftclick bring up the assigned home page</h2>
  465. <p>Add the following code to the bottom of the mouse action list:</p>
  466. <pre class="code"> { ClkAny, MODKEY, 1, loaduri,
  467. { .v = HOMEPAGE } },</pre>
  468. <p>The preceding makes left Ctrl+leftclick go to the home page, just as soon as you define the constant HOMEPAGE. Do that by adding the following code, surrounded on both sides by a blank line, above the current definition of <span class="code">SETPROP</span>:</p>
  469. <h2>Making Right Click on the Tab Strip Create a New Tab</h2>
  470. <p>To complete your mouse-centric functionality, you need to be able to create new tabs with the mouse. You'll enable a right mouse click anywhere on the Tab strip to create a new tab. You'll do this in <span class="code">tabbed.c</span>, not in its <span class="code">config.h</span> include file.</p>
  471. <p>Edit <span class="code">tabbed.c</span> search for function <span class="code">buttonpress()</span>, and look for its <span class="code">for</span> loop. Within the <span class="code">for</span> loop is an <span class="code">if</span> statement, which itself contains a <span class="code">switch</span> statement. The <span class="code">switch</span> statements has cases for buttons 1, 2, 4 and 5. The right mouse button is button 3, so go ahead and add its case between the cases for buttons 2 and 4, as follows:</p>
  472. <pre class="code">
  473. case Button3:
  474. focusonce(i);
  475. spawn(i);
  476. break;
  477. </pre>
  478. <p>Recompile and enjoy your new right click on tab strip creates new tab feature.</p>
  479. <p>My advice to edit <span class="code">tabbed.c</span> goes against the Suckless Tools philosophy, which maintainst that all user changes should happen in the <span class="code">config.h</span> file. But in this case, the only way to do it is in the <span class="code">tabbed.c</span> file, because unlike the Surf source code, Tabbed doesn't maintain an array of possible mouse events in its <span class="code">config.h</span>, but instead hard codes responses to mouse events within <span class="code">tabbed.c</span>.</p>
  480. <h1 id="integration">Integrating Tabbed and Surf With Other Programs</h1>
  481. <p>The guys from Suckless Tools are quite clever. In the Surf distribution, they give you a shellscript called <span class="code">surf-open.sh</span> which your email and IRC clients and other programs can call just the same way they call Firefox or Chromium, and if Tabbed is running, the desired website becomes one more tab. If Tabbed isn't yet running, <span class="code">surf-open.sh</span> starts Tabbed with a tab showing the requested URL. Behold the power of minimalism: They've built Tabbed and Surf as tiny tools that do one thing and do it well, so that with their 32 line shellscript <span class="code">surf-open.sh</span> Surf can act like the bigshot browsers.</p>
  482. <div class="danger">
  483. <p class="title">Danger!</p>
  484. <p>If your installation intermediately exhibits the dreaded webkit "browser program vanishes" symptom, you must either change every <span class="code">-e</span> to <span class="code">-pe</span> in <span class="code">surf-open.sh</span>, or you must configure Surf to <a href="#pluginornot">start without plugins</a>.</p>
  485. </div>
  486. <p>Running <span class="code">make install</span> doesn't automatically put <span class="code">surf-open.sh</span> on your path, so you need to copy it to a location on your path.</p>
  487. <p>The final step is to tell your other programs to use <span class="code">surf-open.sh</span> as your browser.</p>
  488. <p>Clicking a URL in an email or IRC post and having it show up in the one and only Tabbed program might not be your cup of tea, especially if you make heavy use of workspaces. Sometimes you don't want to hunt for your browser: You want it to pop right up, even if it's a separate window adding to the mess. If this paragraph describes you, then instead of using <span class="code">surf-open.sh</span> for the application's browser, use <span class="code">surf&#160;-p</span>.</p>
  489. <h1 id="sucklessadvantage">The Suckless Tools Advantage</h1>
  490. <p>The <a href="#mouseprimary">preceding article</a> showcases one of the Suckless Tools advantages: The fact that a mere mortal can actually change it. Now I'm not average: I spent 15 years as a professional developer, ten of which I spent doing C. So I can read well written code, and I used that ability to look over the less than 4000 lines of Surf plus Tabbed code to figure out what to do. Now imagine me doing the same thing on Firefox. Or Libreoffice. Or systemd. I'd spend a half hour scanning the more than a hundred thousand lines of code, give up in frustration, and either use something from Suckless Tools or write my own.</p>
  491. <p>Suckless Tools makes their software short, simple, organized, and well commented. Suckless Tools programs have no runtime config files. Instead, ordinary config changes can be done by non-programmers in the <span class="code">config.h</span> program, using the well laid out comments and matrix like arrays of structs, and then compiled. Even fixing flaws in their program or adding features not anticipated (like right click makes new tab) are quite doable by someone who knows a little C, because in almost every case you can compare and contrast similar code (such as <span class="code">keypress()</span> vs <span class="code">buttonrelease()</span> or making a copy of an existing mouse event array element and changing its button and callback function and args). The folks at Suckless Tools have written their software to be modified by mere mere mortals, and they've succeeded mightily.</p>
  492. <p>An often stated benefit of Free Software is if you don't like it, you can change it. Of course, this is usually propaganda. I don't like systemd, but I don't have the tech chops to modify udev to not depend on systemd. Both udev and systemd are maintained by paid teams, not by one guy, as far as I know. But with Suckless Tools software, one guy really can change them.</p>
  493. <p>And speaking of systemd, did you know that Suckless Tools offers Suckless Init, an 83 lines of C program that acts as PID1 and can be combined with daemontools-encore to make a complete init system that yes, a mere mortal <em>can</em> understand? They created dmenu, the greatest small software component ever produced: You can use it to acquire choices and text throughout all your software and shellscripts. </p>
  494. <p>From Suckless Tools, you can get a lightweight terminal called st, a lightweight but supposedly efficient shell called mksh, a reliable screen locker called slock, a complete tiled window manager called dwm, assembled from Suckless Tools and other simple software, a Plan 9 toolset called 9base, and lots more. If you're a DIY software person who likes bolting software together, Suckless Tools is a treasure trove.</p>
  495. <p>It's no accident that the Suckless Tools project has created arguably the most stable and productive browser. The Suckless Tools project operates according to a philosophy that almost guarantees minimal bugs, minimal unexpected behavior, minimal negative interaction with other software, and maximum ability to mix and match its tools into the system of your choice, as long as stability and performance are prioritized above "pretty."</p>
  496. <p>For starters, Suckless Tools programs are kept short. Surf's source code is less than 2000 lines, assuming you're not counting the code within Webkit and GTK. The Tabbed program has less than 1500 lines of source. The dmenu program has less than 1300 lines. The three of them fit together to make a tabbed browser with user input acquisition and a menu of tabs provided by dmenu. Both Tabbed and dmenu are designed from the bottom up to be generic tools.</p>
  497. <p>For instance, Tabbed can be used to provide tabs for non-tabbed programs. Ever want a tabbed version of xterm? The following command gives it to you:</p>
  498. <pre class="code">tabbed xterm -into</pre>
  499. <p>I never before used urxvt because of its lack of tabs and tiny fonts. The following solves both problems:</p>
  500. <pre class="code">tabbed -g 900x600 urxvt -fn xft:mono:size=10:weight=bold -embed</pre>
  501. <div class="note">
  502. <p class="title">Careful!</p>
  503. <p>If you use Tabbed's <span class="code">-g</span> geometry option, you can't resize its window in the window manager, either by dragging corners or by clicking the maximize button. Over the long haul, you might be happier not specifying <span class="code">-g</span>, and adjusting manually.</p>
  504. </div>
  505. <p>The dmenu program is known far and wide as the ultimate GUI picklist and input field tool, easily used with lots of other programs. It's also a trivial way for you to acquire user input in your programs and shellscripts. Many people use it hundreds of times daily to run programs. Dmenu is the great window manager equalizer, rendering the window manager's menu and other program running features moot. If you need to write a quick and dirty application, dmenu is your friend. You can integrate dmenu with any software that can receive input from a shellscript.</p>
  506. <p>Complexity reduction is a top priority with Suckless Tools. The Suckless Tools project realizes that complexity is costly, in terms of providing nooks and crannies for bugs to hide, in terms of difficulty making changes, in terms of understanding how the program works, and in terms of performance.</p>
  507. <p>A part of complexity reduction is keeping dependencies to a minimum. In this Freedesktop.Org, Redhat, Systemd "age of integration", an age in which the word "encapsulation" has been forgotten, it's a pleasure to work with small executables with thin interfaces that can be assembled into any software you desire, at the shellscript level, via those thin interfaces.</p>
  508. <h2>A New Age of DIY?</h2>
  509. <p>There was a time when Linux was, by necessity, DIY. As time went on, it became ever less so, opening Linux to a wider and wider audience. But from my viewing angle, the march away from DIY went too far. Browser are now feature-packed, or, as I view it, feature-encumbered, so today they're slow, crashy, and always surprising. OS level user interfaces like KDE, Gnome and Unity constantly get in the way, often perceptibly slowing fast machines, and making moderate machines crawl. Now the Xfce desktop environment is following in their footsteps. Gnome now cares what init system you use: Modern Gnome runs only on computers initted with systemd. Huh? Six or seven years ago the Kmail email client got so complex as to be almost unuseable. Now Thunderbird can take hours to sync up with an IMAP server <em>on the same computer</em>.</p>
  510. <p>Much of this bloatware is created by tight compile-time binding with many libraries, via thick and complex interfaces. If one of the libraries gets a bug, the software using it becomes buggy too. Good software gone bad: Who hasn't experienced switching from one to another to another and back again in a category of software, as various programs stop doing what's needed or start acting erratic?</p>
  511. <p>And then there are the "great new ideas" from the developers, each one requiring you to substantially alter your work flow, which is pretty funny, considering that your original workflow was probably modeled to accommodate your workarounds for applications that were procedurally or ergonomically inefficient. Some free software library developer decides it would improve his career to re-code his creation in Newfad.js plus Object Haskell, and now <em>you</em> need to change your work habits and even your shellscripts.</p>
  512. <p>DIY stands for <strong>Do</strong> <strong>I</strong>t <strong>Y</strong>ourself. The alternative to DIY is HIDTY: <strong>H</strong>ave <strong>I</strong>t <strong>D</strong>one <strong>T</strong>o <strong>Y</strong>ou. With HIDTY, some developer makes a decision or mistake, and you have to adapt your habits, or perhaps go searching for different software. It happens over and over again. HIDTY is the way of life of the Windows user. Over the years, HIDTY has presented us with ever more complex software on Linux.</p>
  513. <p>Till recently, HIDTY has been the exclusive trend on Linux. Those with mental blocks against shellscripting and simple Pythoning had no choice but HIDTY, and even programmers went with HIDTY with explanations like "I don't have time to program my machine." But lately, HIDTY fiascos like Kmail2 and systemd have caused those with programming chops to change that mantra to "I don't have time to adapt to every experiment these devels decide to do." In the past three to five years, more than a few computer users have gone DIY, opting for simple software that does one thing and does it well, freeing them from playing catch-up with the latest version of bloatware.</p>
  514. <p>And more and more, this new group of DIY computer users is discovering Suckless Tools.</p>
  515. <h1 id="acquiredtaste">Surf: An Acquired Taste</h1>
  516. <p>I doubt anybody envisions Surf when discussing browsers. But as you get used to it, you appreciate it. You appreciate its productive keyboard interface. For me, Surf started out as a refuge to the problems I was having with Firefox, Palemoon and Chromium. Surf meant settling for less than my ideal just to get stability and performance. But as I got used to it, I began to appreciate its efficient use of screen real estate and its stability, even on crazy sites. I appreciate its keyboard-centricity, without giving up efficient mousery. I appreciate the superb way it handles Youtube videos. And finally, I fell in love with the way I can program it with whatever features <em>I</em> want.</p>
  517. <p>When you switch to Surf, be aware that you can't truly evaluate it until you've been using it as your primary browser for a week. And even then, you can't really evaluate it unless you've configured it to meet <em>your</em> needs.</p>
  518. <h1 id="wrapup">Wrapup</h1>
  519. <p>In the last few years, mainstream browsers have declined in performance and stability to the point where people are willing to sacrifice features for stability and performance, bringing a new relevance to the Surf browser from Suckless Tools. Surf devotes all its screen real estate to the web page under examination. Surf is remarkably well suited to control via the keyboard. This document has shown you how to compile your own Surf in order to have a user interface that exactly matches your way of working. In the hands of someone unafraid of changing a little C code, Surf is a browser custom made to you. This has been a very long document because this document is the most complete documentation of Surf on the planet. Bookmark this document.</p>
  520. <p>If you've been falling out of love with Firefox, Chromium, Palemoon, Qupzilla and the crew, you owe it to yourself to investigate Surf. If you've begun feeling uneasy with big software that frequently stops working, be sure to investigate <a href="http://suckless.org">Suckless Tools</a>.</p>
  521. <hr/>
  522. <p>[ <a href="../utp/tcourses.htm">Training</a> | <a href="../troubleshooters.htm">Troubleshooters.Com</a>
  523. | <a href="../email_steve_litt.htm">Email
  524. Steve Litt</a> ]</p>
  525. <br class="bottompage"/>
  526. </div>
  527. </div>
  528. </body></html>