Skip to content

Latest commit

 

History

History
217 lines (172 loc) · 10.1 KB

progress-so-far.md

File metadata and controls

217 lines (172 loc) · 10.1 KB

Progress so far

A bit of a high level change log of what we've done so far in the series and what's up next. This isn't a full project roadmap by any means but it should serve as a bit of a guide for where to find things and where we're heading.

NOTE: Code coming from the episodes should have commit messages prefixed with the episode number they came from so that you can look up where changes came from relatively easily.

ep42: found the meaning of life (bound to "M-S-/")

Ep01

Bootstrapping our window manager

We went through setting up our initial main.rs following the steps covered in the getting started guide in the Penrose docsite (along with some helper scripts to make things a little smoother to iterate on going forward). What we end up with is pretty bare bones but it works and we have a starting point to start iterating on our window manager!

  • Initial crate with dependencies
  • Copy in the main.rs from the minimal example in GitHub
  • Makefile and helper scripts
  • xsession file

Ep02

Making things a little more comfortable to live in

Minimal really does mean minimal: there's not much here to start so lets hook up some quality of life improvements we can copy from the examples so that we have a decent working environment to start customising things.

  • Add in EWMH hooks so that programs which need EWMH properties can find them
  • Set up a simple status bar (also requires telling the layouts to reserve screen space)
  • Take a look at layouts and the built in layout algorithms
  • Logout / restart keybindings

Ep03

Configuring keybindings

Now that we have something that's a little nicer to live in we can start digging in to specfic things work. This episode we're taking a look at keybindings: how they work, how to write custom KeyEventHandlers and what Penrose is doing behind the scenes with your bindings to update your window manager state.


Ep04

Hooking into window manager execution

In addition to running your own code in response to a key binding, you can also set up custom hooks to tell Penrose to run some additional logic when specific parts of the window manager event loop are hit. In this episode we take a look at what the different hook points are, the traits involved for writing hooks and we have a go at writing each kind of hook.


Ep05

State extensions, scratchpads and the statusbar

Sometimes you find yourself needing to make use of persistant state that is not provided by the window manager itself. There are lots of ways to achieve this in Rust but one easy way to track state which you are using for your bindings and hooks is to use a state extension. In this episode we take a look at what a state extension is, how to set one up and where some of the code provided in the main Penrose crates makes use of them.


Ep06

Writing status bar widgets

The status bar provided by the penrose-ui crate allows you to write simple text based widgets which you can drive from your window manager state or external data sources. The default set up is configured to mimic the status bar from dwm with the root window name being used as a way of placing arbitrary text in your status bar. The widget support in penrose-ui extends this idea to allow you to drive individual sections of the bar using custom code. In this episode we go over how the status bar works and how you can write your own widgets to extend the behaviour.


Ep07

Writing a custom layout

One of the most appealing things about a tiling window manager is having layout algorithms automatically position your windows for you on the screen. Penrose comes with a few simple algorithms out of the box and in this episode we'll write a new one, show how to work with the Rect struct to easily divide up screen space.


Ep08

Handling layout messages and fun with layout transformers

As we've already seen with the MainAndStack layout, it is possible to modify how the active layout is working by sending it Messages. These allow us to bind keys to changes in our layout behaviour in pretty much any way that we want! For layouts that are not implemented by us, there is the LayoutTransformer trait which allows for per-layout modifications to how layouts run (similar to a layout hook). There are a couple of built-in layout transformers available to use but it is also possible to hand write our own higher-order layouts in order to really customise how things work.

  • Sending dynamically typed messages to layouts
  • Handling messages in our layout
  • Applying layout transformers to existing layouts
  • Writing a custom meta-layout because we can
    • This last one might sound intimidating but it's actually pretty easy!

Ep09

A look at the "pure state" of Penrose

The internal design of Penrose following the 0.3 rewrite is heavily inspired by the approach taken by XMonad (as opposed to dwm which was the case in the original design). The main idea is to split the core of the library into two parts:

  • Pure data structures that have nothing to do with X code
  • Handler code and API wrappers for interfacing with the X server

Today, we're going to have a look at the pure data structures and how they operate. They are based on a technique called Zippers which are a way of encoding the concept of a focused element within a larger collection-like data structure.

The penrose book in GitHub Pages has more information on how all of this works:

The data structures used by Penrose are heavily inspired by those found in XMonad: if you are happy reading Haskell then the following links are worth a look!