 I've been getting a lot of questions recently about Xmonad because I haven't made a video about the Xmonad Tiling Window Manager in a while. And I've made a lot of videos about it in the past, so if you guys are interested, you're just now starting with Xmonad or maybe you're just now starting with Tiling Window Managers in general, go check out some of those older videos that I've done on Xmonad. They'll really help. But today what I wanted to do was I wanted to show you guys my current configuration file because I'm always tweaking things in my Xmonad config. So I'm going to go through my very massive Xmonad config file and I'm going to break down every section of my config file and explain exactly what those little snippets of code do. So let me switch over to the desktop here. Of course, this is Xmonad. If I opened a few terminals here, you can see that's the standard master and stack layout there in Xmonad. The panel at the top is Xmobar. Now let me go over my config. I'm going to go over my config section by section and show you guys exactly what's going on, how I get all the effects and everything that I want in my Xmonad. And hopefully you guys can glean a little information, take parts of my config that you guys may want, throw away the parts that you don't want. So let me open up Doom Emacs and I'm going to open up my Xmonad config. And my Xmonad config is normally a literate config. It is an org document. So it's going to have a lot of comments and everything. Now your Xmonad config is just going to be a Haskell file. So your Xmonad config is actually going to be Xmonad.hs. It's going to be in your home directory slash .xmonad slash Xmonad.hs. And that's just a Haskell document. The org document is the same as just, I have comments. It's the only thing writing it as an org file here in Emacs. It's a little cleaner and easier to read. So I just wanted to explain the difference why my Xmonad config may look a little bit different because I'm going to have bullet points and everything. Just ignore those. Yours is just going to be nothing but straight Haskell, of course. So going over a little bit of my Xmonad config here, the very first section of your config is likely going to be a section of imports. This is where you import various Xmonad contrib libraries. Let me zoom in here a little bit so we can better read some of this. So when you install Xmonad, typically you install two programs to install Xmonad. You install Xmonad, which is the base window manager with the base packages. It's very small. Xmonad is a very minimal kind of window manager, very suckless, even though it's not a suckless program. But you also need to install Xmonad dash contrib. What is this? This is a set of extra modules that you probably are going to want. Most of these modules are what are actually being imported in my config. These are these extra third party modules in the Xmonad contrib package that allow you to extend Xmonad in some ways that you can't with the base package. So if I go over to the browser here, and this is what you guys need to do, I would bookmark this page. This is from Haskell.org. They have a search engine called Hackage that you can look up various Haskell modules and things like that. And I'm looking up Xmonad dash contrib. I will link to this page in the show description, but Xmonad dash contrib is the third party extensions for Xmonad. So again, when you install Xmonad, you also need to install Xmonad dash contrib. And if I go through the documentation here, we have modules. And there are, I don't know, probably a hundred of them. It's a very long list of modules. These modules are what you end up importing here in your config. You see, you know, things like import Xmonad dot actions dot copy window. And if I got into my Xmonad contrib documentation here, Xmonad actions dot copy window right there. For some reason, I needed this particular module. What does it do? It provides bindings to duplicate a window on multiple workspaces providing DWM like tagging functionality. So I actually don't use this. I added it to my config file, probably because somebody else needed it at some point. You know, I have got a lot of people, hey, Xmonad doesn't work like DWM. How do I do this? Xmonad doesn't work like awesome. How do I do that? You know, Xmonad doesn't work like I3. How do I do this? So I do have a lot of extra stuff in my config file that I don't actually use. But anyway, this is what you do. You go in here and find all these third party modules that do, you know, whatever it is that you need to get done in your Xmonad config, and then you import those modules. So that is the import section here. And I've got a lot of things imported in mind. I'm actually going to scroll back up to the imports because I do want to just briefly cover what some of the various imported modules do. I'm not specifically, but the sections. For example, we have import and then Xmonad dot actions dot name of module. So these are various action modules. For example, the copy window kill one, that's to kill a window with a key binding is what that is move to shift to next screen previous screen. These are actions that you do on windows to move them amongst different workspaces, you know, swap between different monitors and things like that. So that's the actions modules. And then you have a data section here. And this is where I do things like import data dot char. So data characters is space and to upper. I know to upper is a module that basically takes a string of characters and makes it uppercase. So I know what that one is. So we have the hooks section here. This is import Xmonad dot hooks dot name of module. And these are typically hooks related to XMO bar especially, such as the dynamic log hook. These are things that we're going to use for our XMO bar config Xmonad dot hooks dot manage docs is another very important one because that includes modules for doing things like avoid struts. Avoid struts is the reason the window does not cover up the XMO bar panel. So that's avoiding struts toggle struts is toggling on that functionality. So I have a key binding in my Xmonad config where if I do super enter, I actually turn off the avoid struts. So it toggles the struts, right? So by clicking my window no longer respects that there's a panel on the screen, right? It just takes up the full screen real estate 100%. It also toggles off the borders. That's a different module that I've imported. So I have that key binding that toggles struts and turns off borders. And if I toggle it again, of course, I get back into the normal avoid struts where it respects the screen real estate at the top that should be occupied by XMO bar. The next section of imported modules is Xmonad dot layout dot name of module. And these, of course, are layouts. So grid variants, grid. So that's for the grid layout. So if I open up a second window here, I'm going to open up four windows. And if I do super tab on my config changes the layouts. And if I get to this one here, this is the grid layout. And I have that grid layout because I imported that grid module there. And then Xmonad dot layout dot simplest float is a floating layout spiral resizable tile tab. I have a tab to layout three columns. I have a three column to layout where everything is in three columns dividing the screen vertically. I also have this section of what I call layout modifiers. These aren't necessarily layouts, but these modify layouts. So for example, the no borders layout here. So I showed you that, you know, I can get rid of the borders by hitting super enter. It toggles struts and it does the no borders command. It actually does two things when I do that command. That's not a layout in itself, no borders, but it is a modifier to any layout. I can actually make any layout toggle on and off no borders if I want to. Also under the layout modifiers, I have Xmonad dot layout dot show W name. That's show workspace name. And this is an interesting little bling effect. So right now I'm on workspace two, which is WWW. Workspace three is called Sys. Let me go to workspace three. So I'm going to do super three on the keyboard. And you see in the center of the screen, it told me what workspace I just went to. Let me go back to workspace two, super two. And it tells me WWW. I just went back to the WWW workspace. Now, that's a really neat kind of effect. Is it that useful? No, because I mean, I have a panel at the top of the screen. I never not know what workspace I'm on, but it is a really neat effect. Scrolling down a little bit, I also have imported a lot of Xmonad prompts. Prompts, for example, for man page, for pass, that's the Unix pass store. We have a shell prompt, SSH prompt, a Unicode prompt and the Xmonad prompt, which is a prompt that gives me Xmonad commands. So what are Xmonad prompts? Well, let me do super shift enter in my config brings up a run prompt. And this is just a standard run prompt. If I wanted to run a Lackardy, for example, I just start typing ALA. And if I hit enter, you know, it opens up my Lackardy terminal. That is the standard run prompt. Now, if I wanted to show you some of these other prompts, if I do super P followed by a M, this is the man page prompt. If I wanted the man page for the LS command, you know, I could type LS and hit enter and get a man page pop up for LS. The SSH prompt is just a SSH and a remote servers. The Unicode prompt is to search through Unicode characters for emojis and then have it copied to a clipboard. And the Xmonad prompt, again, is Xmonad commands. So if I do super P followed by X, this is the Xmonad prompt. And you can see it's viewing workspaces, shifting to different workspaces, killing Xmonad, restarting Xmonad, you know, it's Xmonad specific commands in that particular prompt. Now, scrolling down a little further, I have a section in my config I call variables. This is just setting variables that you're going to use later in your config file. If you have a string of characters that appears many, many times in your config, for example, my key bindings and my key bindings, I have key bindings for a lot of terminal based applications. Matter of fact, let me go down to the bottom of my config to my key bindings and I will show you some of this. So these are my key bindings and let me find some that involve my terminal right here. For example, super enter mod return spawns my terminal plus plus dash e fish. So it launches my terminal and then launches the fish shield. This looks like a super alt H launches my terminal and then it launches H top. So let me try that super alt H and it launches my terminal and then H top within my terminal. And I've got a lot of these commands that involve my terminal. So let me get back to the top here to my variables. And I have a variable that I set called my terminal and I set it to equal alacrity. Why did I do that? Well, if I have a dozen different key bindings in my config that involve a terminal. And what if I change my default terminal? What if a month from now I no longer want to use alacrity as my standard default terminal? Maybe I want to switch to URX VT. Well, instead of having to go change a dozen different key bindings and changing alacrity a dozen different times in those key bindings. Since I use this variable in those key bindings, my terminal, all I have to do is change this one variable. And, you know, right then and there, you know, if I save and restart Xmonet, all those key bindings now are using X, URX VT as the terminal rather than alacrity. It just saves you from having to change a ton of lines later. Now I actually don't want to use URX VT because I don't even have it installed. So I'm going to go back to alacrity. I have a lot of key bindings that also involve my browser. So I set my browser to be cute browser and my cute browser binding is cute browser with a space behind it. Because these key bindings that will use cute browser will be cute browser space and then name of website, you know, URL of website. And you need a space somewhere. You either need that space to be at the end of cute browser in the variable or just remember in the key bindings themselves to add a space in the appropriate spot. But you do need to make sure when you do these variables, if it involves the terminal and the browser and then some extra information, some other arguments, make sure you place the space in the correct places. Some other things I said, I set a variable for my font, my emoji font. I set variables for normal color, focus color, border with the key that I want to be the mod key should be somewhere in here. It's right here. It's mod mask. My mod mask equals mod for mass that sets the mod key to be the super key. I also set alt mask to be mod one mass. So alt mass means it's the alt key. So any key binding or anything that refers to alt mask actually refers to the alt key. I could change that, of course, to some other key if I wanted. The next section of my config is the auto start section. So I have this here, my startup hook equals do. And then after do, I have spawn once name a program, spawn once name a program, spawn once name a program, basically a command to run. And this is where I put all the programs that I want to automatically start as soon as Xmonad starts. So when Xmonad starts up, I want LX session to run. That's, you know, the session manager. I want that to run in the background. I also want to spawn once nitrogen dash, dash restore. That sets my wallpaper. Because if I don't have something that sets my wallpaper as soon as I log into Xmonad, I'm just going to have a black background. And then I spawn once Pycom, Pycom is the compositor. I spawn once Trayer. Trayer is the system tray here at the end of X-Mobar. That's actually a separate program from X-Mobar. It's a completely separate program. So that's Trayer. And then within the system tray, Trayer, I have network manager applet volume icon. I also auto start the Emacs daemon because I use Emacs client as my editor. And if you're going to use Emacs client, you have to have the Emacs server running the Emacs daemon running. So how do I accomplish that? Well, I just put it in my startup hook here in Xmonad. I also have a couple of daemons that I've commented out in Haskell to do a comment. You do two dashes. I used to use the cocoon editor and I used to start cocoon as a daemon. I also have URX-VT-D. That's the URX-VT terminal daemon. I no longer use URX-VT because I use Elecrity. But if I did use URX-VT, I would definitely use the daemon running in the background. The next section of my config is called grid select. Now, grid select is interesting. It's this interesting little effect that let me show you guys grid select. That is grid select. It's just a grid of programs that I have set. I guess you could call it almost like quick launcher kind of programs. Instead of doing it the traditional way where you have quick launchers, maybe with icons sitting in a panel that you could click on. And Xmonad, if you wanted, you know, some kind of quick launcher kind of applet, I would probably just use this grid select menu and you could do the VM keys, HJKL, or up, down, left, right. If you could use the arrow keys, for example, if I wanted to, I could scroll over here to a dead beef. If I wanted to, and I could launch my dead beef music player. It looks like I was listening to Hart's greatest hits the last time I was listening to something in dead beef. Now, my grid select config gets a little deep, very detailed here. I'm not going to cover everything in my grid select, but you guys can check that out on your own. The next section, similar to grid select, there is a feature called tree select. It's a tree menu. So in my config, if I do control T followed by T, this is my tree select menu, and I could use the VM keys to navigate down and I could go, I don't know, into bookmarks here, into Linux, into Arch Linux. And then finally go to the ArchWiki and hit enter. And this should launch, it should have launched a Kube browser, but it looks like Kube browser has an error. I haven't actually run Kube browser in a couple of weeks. I'm assuming what has happened is Kube browser probably has had an update recently and their update broke my config.py, which is the config file for Kube browser. So I need to investigate that issue. But again, the tree select menu is this really neat tree kind of menu. If I go through here and I go to multimedia and I go down to VLC. I don't think I have VLC installed. Do I? Yes, I do. All right. So I can launch programs. I can go through. I can set bookmarks in the tree select menu. You can add anything you want to to the tree select menu here. It's pretty self-explanatory. I have a ton of stuff in my tree select. I'm not going to go over all the tree select settings. You guys can investigate that further. If you're interested, grid select and tree select, they're kind of cool, but they're probably not something that most people are going to want in their config. So I'm not going to spend a ton of time on that. I will spend some time on the X-mone ad prompts. So I showed you where you import the various X-mone ad prompts. The modules you're going to use. This is setting some settings for those prompts, things like, what do I want the color to be, the foreground color, the background color? What do I want the font to be? I want the font to be my font. Remember, I set a variable at the top of my config for setting my font. That saves me from having to type that very long string, you know, XFT, colon, name of font and all of that. I just set a variable one time. And anytime I need to call upon that font, I just set it to my font. So that's one of the reasons why I have that particular variable. But you guys can check out these. They're called XP configs for X prompt configs. I called mine DT XP config because I changed some things from the default XP config. I have a section here called custom prompts. These are X prompts, but these are custom prompts. Now I'm not a Haskell master. I don't know much about Haskell. I know enough to hack on my X monad config, but basically I found these snippets of Haskell somewhere, probably on Stack Overflow. Right. So this calc prompt, if I do super PC for calculator, I have this calculator prompt here where I could do something like two plus two and hit enter and it says two plus two equals four. And then I get another prompt and then I could do, I don't know, how about four times four and four times four equals 16. And then, of course, I get the prompt again. And that is achieved by this little bit of Haskell code here. Of course, I had to import the X monad prompt module. But after that, it's really just a few lines of Haskell made that happen. This particular calculator prompt uses a program called calculate dash GTK. So you do have to have that installed on the system. If you're going to use this calculator prompt. I also have this edit prompt here. And this is just a way for me to get a run prompt. Type a path to a file and it will open in Emacs. It's not a very useful prompt. It's just me playing around with trying to figure out how X monad prompts work. So I'm actually not going to spend time talking about that, but I left it in the config here just in case you guys want to investigate it because maybe you want to see how the code works. That's why I left it there in case I ever want to come back and try to figure out how to create my own custom X monad prompts. And that's really the only reason I have the calculator prompt or the edit prompt here is just for educational purposes. X prompt key map are key bindings that work when you're inside one of these, you know, X prompts. So anytime you launch one of the X monad run prompts or SSH prompts or anything, these key binding should work within those prompts. I have a search engine section to my config where I can search various search engines. So this lengthy list right here is all the search engines that are available for me to search from directly from an X monad prompt. So I have this list of search engines. And most of these search engines are built into an X monad contrib module called, I believe it's X monad dot actions dot search. But I wanted to add some that were not part of that module. And you can see right here, I have these six search engines here. I added these. These were not part of the module, but I wanted to add them. So I have these lines here and then down here where I have the complete search engine list, the ones that begin with a capital S, such as S dot dot go. Those were the ones that were already built into the module. The ones that don't begin with S dot, such as this arch wiki search engine right here, that was one of the custom ones that I added to see these search prompts in action, which you want to do in my config. I have super S followed by a key and the key that you need to hit will depend on which search engines, for example, arch wiki. The key is a duck duck go. The key is D. I hope that makes sense. So if I do super S a, we can search the arch wiki. I can search for, I don't know, flat pack, and it should open the flat pack page from the arch wiki inside a cute browser. But again, my cute browser config may be broken. So now that I think about it recently, I did change my web browser, my default web browser on my system. It's always been Firefox. And recently I removed Firefox from my machine. And it still may be set as my default browser. So that may be what these key bindings are trying to find. It's trying to find Firefox and it's no longer on my system. This video is going to run very long. So just very briefly, I do want to cover three really important sections of my config. That's the layouts, the key bindings, and then the actual main section of the config. So the layouts, this is where I define, of course, the layouts that I use, such as the default tall layout, which I'm in now, which is the master and stack layout. But if I do super tab, I can go through a bunch of different layouts. Let me open some windows so you can see this is the master and stack layout. This is a magnified layout where whichever window has focus, it zooms itself in really neat little layout. This is the monocle layout. So full screen, everything stacked on top of each other full screen. But it does leave room for the bar at the top. And then this is the floating layout. So all the windows float now, I could grab them with the mouse and move them around. This is the tab layout. You can see we have tabs at the top here. Of course, you can use the mouse to click on the tabs. You can also use the keyboard to navigate through the tabs. And then I have a grid layout, have the spiral layout, where if I kept opening windows, you know, things would just keep spiraling around. And then I have the three column layout, which is three columns as a master and stack three columns, where the first column is a little bigger. Then the other two columns and then three row layout is similar to three columns. And then finally, master and stack again, the tall layout. And you can see I've defined all those layouts here in this section. I also have these lines here about spacing, the my spacing and then the my spacing prime here. This is how I get gaps around the windows. I'm just setting specific numbers for the pixel size of gaps I want around the windows in each different layout. For example, in the tall layout, the master and stack layout, I have my spacing eight. That's setting the spacing around the windows to be eight pixels. Scrolling down past the layout section, I have the show window name, the workspace name that is. And this is where I set the font size and the colors for that neat effect that I get when I switch workspaces where you get the workspace name here. And then we get to the actual workspaces themselves. I've set the workspace names, dev, www, sys, doc, vbox, chat, muse, vid, graphics. And those are the nine workspaces here in X-mode bar. They are clickable. I can actually click on them with the mouse if I wanted to. I sometimes forget that those things are clickable because most of the time, of course, you're going to use the keyboard, of course, to switch workspaces. And this is a section that I've cleaned up a bit recently. This section used to be quite a bit bigger. I used to have two different sections, one for non-clickable workspaces and one for clickable workspaces, depending on which one you want to use. I condensed it down, though, and to just having clickable workspaces. And I've made the code a little cleaner, too. This code was actually suggested from somebody over on my GitLab. They opened up an issue and actually gave me a little bit cleaner Haskell here to get that clickable workspace effect and with the names not really being affected because before the code, I was using the names of the workspaces that appeared on the screen were really long because the names of the workspaces were this here. Action equals X do tool key super plus plus because that's the actual workspace. You see clickable workspace equals. And so that's the workspace name. Well, he gave me this code here where it changes the workspace names from this action here, the clickable action, you know, clicking on the workspaces to the actual names. So I really appreciate that. I should have went to my GitLab and got that guy's name that left me that code. But I really appreciate the tip there. Manage hook here. This is setting window rules. For example, when I open up Firefox, which is no longer on my system, it automatically opens up Firefox on workspace to the code. Remember, in programming, typically everything starts at zero. So if you have 10 workspaces, it's zero through nine, not one through 10. So do shift my workspace. Exclamation point, exclamation point one is actually sending Firefox to workspace two because workspace one would actually be zero. I hope that makes sense. So that's how the manage hook section works for giving you some window rules as far as what workspaces they appear and what layout they appear, whether they're floating or what have you. The key binding section is pretty self-explanatory. I have my keys home equals and then this very long list of key bindings. And you can see what the key bindings are. The capital M is the mod key. That's the super key. Capital S is shift. Capital M one is alt. Capital C is control. And I am using the easy key bindings here in my config. So if I go back to the top and go to import and somewhere in import, I believe utils, import exponent add dot util dot easy config. That is how you get the easy config key bindings rather than the standard key bindings. The standard key bindings in Xmonad look something like this. Instead of capital M for the mod key, it's actually mod M, right? And instead of capital C for control, it's control mask. Capital S for shift is really shift mask. Yeah, that's a lot of tedious writing. Well, if you import the Xmonad util easy config module and then you can go in your config and change all of those rather lengthy shift mask, control mask, mod M and all of that to just capital M or capital C, capital S, what have you. And then finally, the last section of my config is the main. This is where everything that I put previously in the config comes together. This is your main block. You have main equals do and then it executes all of this code. And all of this code is basically all the sections from earlier in the config. I have these three sections here. XM proc for XMO bar process because I have three different XMO bar processes going on. I have three monitors and I have three different configs for each of my three XMO bars because I've got different widgets on each of them. I hope that makes sense though. That's why I have three different XM procs there. In XM proc, I could have named that anything. It just made sense XMO bar process zero one and two. And then after I set that, then we have this block here Xmonad dollar symbol and I have EWMH death and death stands for defaults. And then I have this opening brace and then later I'll have an ending brace and everything in between that brace and that brace is really your Xmonad config. This is everything that it all comes together right here. And this is where you tell it, mod mask equals my mod mask. That's the variable I set before. So mod mask equals the super key. Terminal equals my terminal. Again, alacrity is what I set startup hook equals the my startup hook section from earlier. That's all the auto start programs. Layout hook equals the show workspace name and then my layout hook. There's a section earlier my config called my layout hook. It's all the window rules and everything. Workspaces equals the my workspaces section from earlier in my config. You guys get the idea. And then later we've got log hook. Log hook is where all the XMO bar stuff comes together. So that is this section here. And in between these braces here, you have all of these statements that begin with PP. This is a pretty printing libraries here. It's basically what this is. PP output is, hey, what output is getting outputted into the XMO bar? Well, we're getting output from XMProc0, XMProc1 and XMProc2. My three different XMO bar configs that I set earlier and I set exactly what monitors they're on. Zero, one and two for monitors one, two and three. PP current is the XMO bar color config for the current workspace I'm on in XMO bar. So right now I'm on workspace two, www and it's this green color. And then PP visible is the XMO bar workspace color for visible workspaces. So workspaces I have on other monitors, not my current monitor, so I can see them. And so that's workspace one, which is the div. Oh, I shouldn't have clicked it. I forgot these are clickable workspaces. So one and eight are visible workspaces because they're on my first and third monitors. I hope that makes sense. And PP hidden is the workspaces that are not currently viewed on any of my monitors and they are colored purple because I set that right here in the color here. And of course this clickable part makes those workspaces clickable. That's why I can click on them and it will actually take me to those workspaces. So I have all these XMO bar settings here and at the end additional keys and this is where it's setting all of my key bindings. Remember I had the list of key bindings. Well, actually all of that goes right here at the end of the main equals do block. It just makes things easier though, instead of having this massive main equals do block, you break everything down into sections like key bindings and layouts and workspaces. And then you just call upon them here by saying, hey, terminal equals and then my terminal, because you set a variable for it. Workspaces equals my workspaces because you set that block of workspaces earlier in the config. It just makes things a little cleaner. So that was just a little bit of my Xmonad config. Some things have changed since the last time I made a video, but for the most part about 95% of that config is exactly the way it was before. Xmonad has really been my preferred window manager for most of my desktop Linux experience. Since I switched to desktop Linux back in 2008, I spent most of my time in standalone window managers, almost 100% of my time as a desktop Linux user. I've been a window manager user. Done some floating window managers like Openbox, Love, Openbox, spent years playing around in the Openbox and Fluxbox and things like that. But early, early on when I switched to Linux, one of the very first window managers I ever tried was Xmonad. And it's one I keep coming back to because it's just so dang good. I know the config for Xmonad can be tough, especially for newer users, but I hope seeing me go through my config and breaking some things down, I tell you exactly what some of that code is doing. I hope that makes things a little easier. Obviously, I can't completely spoon feed you as far as, you know, I can't tell you how to do things that I don't do. But I often get people asking me support kinds of questions. Hey, I want my window manager to do this. How do I do it? And it's not something that I do in my config, obviously. So I would have to go and learn it myself and figure out how to configure it to somebody else's liking to help them. I'm not gonna do that. At some point, you do have to do some of the heavy lifting yourself. But from this video and some of my past videos, I really think I've done enough that you guys probably can figure out exactly how to get Xmonad set up. Now, before I go, I need to thank a few special people. I need to thank the producers of this episode. I need to thank Absi, Dallas, Gabe, Lou, Mitchell, Alan, Akami, Archie, 2530, Chuck, David, the other David, Dylan, Gregory, Lewis, Paul, Scott, Wes, and Willie. They are my highest tiered patrons over on Patreon. They are the producers of this episode. I also need to thank each and every one of these ladies and gentlemen as well. All these names you're seeing on the screen right now, these are all my supporters over on Patreon because the DistroTube channel does not have any corporate sponsors. I'm sponsored by you guys, the community. If you would like to support my work, look for DT over on Patreon. All right, guys. Peace.