Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/jollm/exlybar

An Emacs Polybar-like window manager status bar.
https://github.com/jollm/exlybar

Last synced: 3 months ago
JSON representation

An Emacs Polybar-like window manager status bar.

Awesome Lists containing this project

README

        

#+TITLE: exlybar

Exlybar is an “Emacs Polybar like thing”.

It aims to act as an X window manager agnostic status bar and system tray that
is written completely in elisp and fully configurable in Emacs.

The most apparent usage scenario at present is to pair it with [[https://github.com/ch11ng/exwm][Exwm]].

It is currently pre version 1.0 and the API is not yet stable.

Like Exwm, it relies on xcb via xelb to communicate with an Xorg server.

Current version: *0.22.4*

Note: *At present this requires Emacs 28.0*
If you would like it to work on Emacs 27, please let me know.

Note: *This probably doesn’t work well with multiple screens at the moment.*

* Contents :TOC:
- [[#synopsis-of-work-in-progress][Synopsis of work in progress]]
- [[#now-supported][Now supported]]
- [[#not-currently-supported-but-planned][Not currently supported (but planned)]]
- [[#project-organization][Project organization]]
- [[#usage-caveats][Usage caveats]]
- [[#installation][Installation]]
- [[#install-directly][Install directly]]
- [[#install-with-use-package][Install with use-package]]
- [[#update-to-latest-git-commit][Update to latest git commit]]
- [[#guix-installation][Guix Installation]]
- [[#usage][Usage]]
- [[#layout-and-display-with-modules][Layout and display with modules]]
- [[#configure][Configure]]
- [[#with-use-package][With use-package]]
- [[#screens][Screen(s)]]
- [[#attribution][Attribution]]
- [[#contact][Contact]]

* Synopsis of work in progress
** Now supported
+ Display at the top of the screen as window a dock window

+ Configurable horizontal module layout support left, center, right align

+ [[https://stumpwm.github.io/][Stumpwm]] like format/color code syntax for arranging module text, icon, and
widget display

+ Rendering of OTF/TTF vector text and icon fonts via [[https://github.com/jollm/fontsloth][fontsloth]]

+ Mix fonts and conditionally change fonts within modules

+ Configurable zone colors to change icon or color text based on status

+ Module development API exists but is not yet finalized or particularly well
documented

+ Act as the system tray (as of version 0.22.0)

* Not currently supported (but planned)
+ Configuration for multiple screens/randr (this is the first priority at
present)
+ Dock somewhere other than the screen top (this should be trivial to implement
but is as yet untested)
+ Help to locate/suggest/select compatible fonts to try
+ Easy and meaningful integration with screen readers
+ Multiple bars and gaps like in Polybar
+ Configurable transparency
+ Investigate adding a render backend that uses a posframe-like window with a
nil parent configured as a dock

This would provide an easier path to eventually decoupling from X and allow
for display in an actual Emacs frame (if desired). It would also allow for
built-in font capabilities.
+ Animations

* Project organization
Exlybar consists of five primary components:
+ Status bar xcb lifecycle, refresh, and event handling
Entry point: [[./exlybar.el]]

This delegates to [[./exlybar-layout.el]] to decide which window areas to
copy/clear during a refresh cycle.

This provides two autoloaded interactive functions:
+ ~(exlybar)~: display the status bar

+ ~(exlybar-exit)~: exit the status bar

+ Logical layout helpers
Entry point: [[./exlybar-layout.el]]

Currently this produces horizontal layouts supporting combination of left,
right, and center alignments of modules. It supports x and y coordinate
offsets.

The extents fns ~exlybar-layout-extents~ and
~exlybar-layout-subtract-extents~ allow for selective display update when the
layout changes.

+ Port of Stumpwm like color command syntax
Entry point: [[./exlybar-color.el]]

These are stumpwm style color/font codes meaning that each module can have a
format string to arrange its text/icon and allow control of fonts and colors
for individual parts or segments.

Not yet all the stumpwm commands have been implemented.

Currently the following color code commands are supported:
- :font, shorthand ^f[0-9]
~exlybar-font-map~ is customizable and maps 0-9 to font paths
- :fg, shorthand ^[0-9]~? ~exlybar-color-map-fg~ is customizable and maps
0-9 to xcb colors The optional ~ suffix (not in stumpwm) indicates to apply
the color locally, meaning only to non color commands preceding the next
color command if any. This is implemented as an implicit :push :pop around
applicable segments.
- :push, shorthand ^[
push the current fg and font onto the stack
- :pop, shorthand ^]
pop the stack and restore the previous fg and font
- ^; (not in stumpwm) acts as a noop to separate non color command
segments. it’s mostly useful in combination with ~ operator described above

+ Base module API

*not yet finalized*

Entry points:
+ [[./exlybar-module-types.el]]
+ [[./exlybar-module.el]]

At present it consists of a cl-struct base type ~exlybar-module~ and a set
of generic functions and default primary methods for dispatch on objects of
that type.

Generic functions (default primary method descriptions):
+ ~(exlybar-module-init (m exlybar-module))~: gives an xcb pixmap, graphics
context, a glyphset, a cache, and fills a rectangle with the background
color.

+ ~(exlybar-module-layout-text (m exlybar-module))~: relies on
~fontsloth-layout~ and ~exlybar-color~ to produce a sequence of color
commands and glyph positions

+ ~(exlybar-module-refresh (m exlybar-module))~: if the module requests a
refresh, draw the text using glyph positions and color commands

+ ~(exlybar-module-exit (m exlybar-module))~: free xcb assets and clear
module state

Module implementations can provide specific :before and/or :after methods of
the above as well as overrides to hook into the module
init/layout/refresh/exit cycle. These should also allow module devs to
provide module specific Emacs hooks.

+ Glyph rendering, loading, and compositing
Entry point: [[./exlybar-render.el]]

This is used by exlybar-module.el to draw text. It relies on [[https://github.com/jollm/fontsloth][fontsloth]] for
glyph rasterization and provides an implementation of glyph stream like
functionality that is normally in xcb-render-util but is not included in xelb
in order to support CompositeGlyphs32 requests for loaded glyphs.

* Usage caveats
*This probably doesn’t work well with multiple screens at the moment.* I only
have a laptop and no extra monitors. I plan to get a multiscreen setup for
testing soon.

*It’s not great at helping to find fonts.* I’m planning to add a font-find
helper that delegates to fc-match. This would be helpful if you don’t happen to
have the default fonts.

*Check [[./exlybar-color.el]] for the default font paths.*

It depends on fontsloth which is another project in very early stages; see the
fontsloth README linked above for a list of tested fonts.

*The module and layout APIs are not yet finalized as such configuration
procedures and customization options may change prior to a 1.0 release.*

* Installation
First follow the instructions to install
[[https://github.com/jollm/fontsloth][fontsloth]] (from MELPA).

Pending upload to MELPA, install using [[https://github.com/quelpa/quelpa][quelpa]].

Quelpa allows an installation directly from this repo that is then managed the
usual way via package.el. Quelpa can be installed from MELPA or bootstrapped
directly from source if desired.

After a successful installation on Emacs 28, ~M-x: exlybar~ should display an
empty status bar docked at the top of the screen. If it does not, please open
an issue. To configure the bar to display one or more of the available modules,
see [[*Usage][Usage]] below.

** Install directly
#+BEGIN_SRC emacs-lisp
;;; after installing quelpa

;; note this uses a MELPA recipe, so the usual MELPA options also apply
(quelpa '(exlybar :fetcher github :repo "jollm/exlybar"
:branch "focal"
:files (:defaults "modules/*.el")))
#+END_SRC

** Install with use-package
First install [[https://github.com/quelpa/quelpa-use-package][quelpa-use-package]] (either with quelpa or from MELPA).

Note: [[https://github.com/radian-software/straight.el][straight.el]] is another option, either standalone or with
use-package.

#+BEGIN_SRC emacs-lisp
;; if quelpa use-package is installed, this should install exlybar
(use-package exlybar
:quelpa ((exlybar :fetcher github :repo "jollm/exlybar"
:branch "focal"
:files (:defaults "modules/*.el"))))

;; if you want to auto-check for upgrades
(use-package exlybar
:quelpa ((exlybar :fetcher github :repo "jollm/exlybar"
:branch "focal"
:files (:defaults "modules/*.el")) :upgrade t))
#+END_SRC

** Update to latest git commit
After installation:
~M-x: quelpa-upgrade~

* Guix Installation

When using guix system/guix package manager to manage Emacs packages,
the below linked package definitions should work from a local channel:

[[./exlybar.scm.org][./exlybar.scm.org]]

Update commit references/tags to the desired revisions/tag names.

To compute the base32 hash, use a command like =guix hash -S nar .=
after checking out the desired revision.

Once the channel definition is updated, run =guix pull=.

Then, =guix install emacs-exlybar= should suffice to complete
installation.

* Usage
** Layout and display with modules
#+begin_src emacs-lisp
;;; this demonstrates display for all modules provided so far
(require 'exlybar)

(require 'exlybar-backlight)
(require 'exlybar-battery)
(require 'exlybar-date)
(require 'exlybar-tray)
(require 'exlybar-volume)
(require 'exlybar-wifi)

;;; layout everything to the right

(defvar my/date (exlybar-date-create))
(push my/date exlybar-modules)

(defvar my/battery (exlybar-battery-create))
(push my/battery exlybar-modules)

(defvar my/backlight (exlybar-backlight-create))
(push my/backlight exlybar-modules)

(defvar my/tray (exlybar-tray-create))
(push my/tray exlybar-modules)

(defvar my/volume (exlybar-volume-create))
(push my/volume exlybar-modules)

(defvar my/wifi (exlybar-wifi-create))
(push my/wifi exlybar-modules)

(exlybar)

;;; re-layout everything current displayed to the left

(push :left exlybar-modules)

;;; re-layout everything in the center

(setq exlybar-modules (cdr exlybar-modules))
(push :center exlybar-modules)

;;; layout tray, wifi, and battery to the left and volume, backlight, and date
;;; to the right

(setq exlybar-modules
`(:left ,my/tray ,my/wifi ,my/battery :right ,my/volume ,my/backlight ,my/date))

;;; exit (exit doesn’t modify layout for next time)

(exlybar-exit)

#+end_src

** Configure
#+begin_src emacs-lisp
;;; please note this is in an early phase and subject to change

(require 'exlybar)

(require 'exlybar-backlight)
(require 'exlybar-battery)
(require 'exlybar-date)
(require 'exlybar-volume)
(require 'exlybar-wifi)

;;; assume one of the layouts demonstrated above

;;; display the bar
(exlybar)

;;; make it taller
(setq exlybar-height 25)

;;; make it shorter
(setq exlybar-height 16)

;;; swap wifi signal quality and essid
(exlybar-module-format my/wifi) ;; show the current format
;; it is "^6^[^f1%i^]^[^2|^]%e^[^2|^]%p"
(setf (exlybar-module-format my/wifi) "^6^[^f1%i^]^[^2|^]%p^[^2|^]%e")

;;; change battery default color to default
(exlybar-module-format my/battery) ;; show the current format
;; it is "^6^[^f1%i^] %b%p%% ^[^2|^] %t ^[^2|^] %r"
(setf (exlybar-module-format my/battery) "^0^[^f1%i^] %b%p%% ^[^2|^] %t ^[^2|^] %r")

;;; change battery percentage thresholds for icon and percent color change
(setq exlybar-battery-color-zones '(40 20 7 t t))
;; see ~exlybar-zone-color~ for an explanation of the list elements

;;; see custom group ~exlybar~ and subgroups for current options

#+end_src

** With use-package
#+begin_src emacs-lisp
(use-package exlybar
:defer t
:config
(require 'exlybar-tray)
(require 'exlybar-date)
(require 'exlybar-wifi)
(require 'exlybar-backlight)
(require 'exlybar-volume)
(require 'exlybar-battery)
(setq my/exly-tray (exlybar-tray-create)
my/exly-date (exlybar-date-create)
my/exly-wifi (exlybar-wifi-create)
my/exly-volume (exlybar-volume-create)
my/exly-backlight (exlybar-backlight-create)
my/exly-battery (exlybar-battery-create))
(setq exlybar-modules (list :left my/exly-tray my/exly-date
:right my/exly-wifi my/exly-volume
my/exly-backlight my/exly-battery)))

;;; then M-x: exlybar
;;; To exit:
;;; M-x: exlybar-exit
#+end_src

* Screen(s)
These are using Bookerly-Regular for variable text, IBMPlexMono for monospace,
and Font Awesome 5 (the one that comes with all-the-icons) for icons:

#+CAPTION: a screenshot of the backlight module
[[./screen-backlight.png]]

#+CAPTION: a screenshot of the battery module
[[./screen-battery.png]]

#+CAPTION: a screenshot of the date module
[[./screen-date.png]]

#+CAPTION: a screenshot of the volume module
[[./screen-volume.png]]

#+CAPTION: a screenshot of the wifi module
[[./screen-wifi.png]]

* Attribution
This project is heavily inspired by daviwil’s [[https://systemcrafters.cc/][System Crafters]] presentations on
Emacs and Exwm as well as [[https://github.com/ch11ng/exwm][Exwm]] itself along with numerous others whom I will
attempt to list as the project develops further. See also attributions for
fontsloth.

Thanks to Fran Ley for helping to maintain this project.

* Contact
I’m currently poselyqualityles on librera chat. Feel free to interact as I’d
like this to be as broadly useful and fun as possible given the current scope
and limitations.

#+ATTR_HTML: :rel license
[[https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png]]
[[http://creativecommons.org/licenses/by-nc-sa/4.0/][This documentation is
licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0
International License.]]

Copyright (C) 2023 Jo Gay