ref: 1c1d3612692ce5568285f1be3b88d2798aef35e6 sxmo-docs-stable/USERGUIDE.md -rw-r--r-- 36.9 KiB
1c1d3612Anjandev Momi add man.sr.ht documentation links to header 8 months ago

#Sxmo: Simple X Mobile - User Guide

Project Overview | Documentation | Documentation (Development Version) | Install Guide | User Guide | Contributing | Images | Demo Video


After login, you will be presented the SXMO interface as follows:


The core of the Sxmo UI is based on the dwm window manager, the dmenu menu system, the lisgd gesture daemon and the svkbd keyboard.

#Status Bar

The status bar located at the top displays the various workspaces that you have in the form of the numbers 1,2,3,4. Tapping one of these numbers will take you to that workspace. Right next to it (the three lines) indicates the dwm layout that is activated (see layouts). The default layout is a vertical stack.

At the top-right you see the status menu, holding various symbols:

  • The first icon indicates the state of the modem and the modem monitor:
    • A lock icon shows your modem's SIM is locked and needs to be unlocked with a PIN
    • A signal bar icon shows that you have a GSM connection
    • A cloud icon shows that you also have a data connection (2G/3G/4G)
  • The wifi icon indicates you are connected to a wireless network
  • The battery icon shows your battery stage and whether it is charging or not (small lightning symbol)
  • Volume is expressed through the speaker icons.
    • When you have the earpiece as audio output, you see a phone handle icon with sound waves
    • When you have headphones as audio output, you see a headphone icon

#Global UI Controls

Button Bindings

The dwm window manager was patched with (among other patches), the multikey patch. This patch allows dwm to recognize rapid successive (e.g. double/triple clicks) button presses to trigger different actions. The three hardware buttons on the Pinephone thus can trigger 9 different actions.

The default button bindings are:

  • Volume Raise:
  • Volume Lower:
    • 1 tap: Toggle dwm layout algorithm (between monocle/tile/bstack)
    • 2 taps: Shift current client in stack
    • 3 taps: Kill client
    • Hold (or 4 taps): Close client
  • Powerkey:
    • 1 tap: Toggle virtual keyboard (svkbd)
    • 2 taps: Launch the terminal (st)
    • 3 taps (or hold): Launch the browser

Swipe gestures

In addition to the button bindings provided through dwm, a custom application called lisgd was developed to provide touchscreen swipe gestures within Sxmo. These gestures are sensitive to the edge of the screen where the gesture is initiated or where they end up, and some are sensitive to the length/distance of the swipe. Gestures in the main part of the screen, staying clear of the edges, are usually not interpreted and passed to the underlying application unmodified (assuming it has gesture support).

The SXMO gestures are visualized in the following schematic:


The default swipe gestures are:

  • 1 finger Right-to-Left from Right edge: Focus next tag/workspace
  • 1 finger Left-to-Right from Left edge: Focus previous tag/workspace
  • 2 fingers Right-to-Left (anywhere): Move focused application to previous tag/workspace
  • 2 fingers Left-to-Right (anywhere): Move focused application to next tag/workspace
  • 1 finger Top-to-Bottom along the Left edge (held pressed): Volume down
  • 1 finger Bottom-to-Top from the Top edge: Show the application menu
  • 2 finger Bottom-to-Top from the Top edge: Show the system menu
  • 1 finger Top-to-Bottom onto the Top edge: Close the active menu
  • 1 finger Bottom-to-Top from the Bottom edge: Show virtual keyboard
  • 1 finger Top-to-Bottom onto the Bottom edge: Hide virtual keyboard
  • 2 finger Top-to-Bottom onto the Bottom edge: Close the current active window
  • 3 finger Top-to-Bottom onto the Bottom edge: Kill the current active window
  • 1 finger from Bottom-Right corner, swiping diagonally: Rotate the screen
  • 1 finger from Bottom-Left corner, swiping diagonally: Lock the device
  • 1 finger Left-to-Right along the top edge (held pressed): Increase screen brightness
  • 1 finger Right-to-Left along the top edge (held pressed): Decrease screen brightness

There are various default gestures that translate to keypresses for the underlying application, this facilitates navigation in a variety of applications, including terminal-based applications, without needing the virtual keyboard:

  • 1 finger Right-to-Left onto the Left edge: Send Left arrow
  • 1 finger Left-to-Right onto the Right edge: Send Right arrow
  • 1 finger Top-to-Bottom along the Right edge (held pressed): Send Key down (scroll down)
  • 1 finger Bottom-to-Top along the Right edge (held pressed): Send Key up (scroll up)
  • 1 finger Right-to-Left along the Bottom edge: Send Backspace
  • 1 finger Left-to-Right along the Bottom edge: Send Return

The sensitivity of the gestures can be controlled, see: user-customizable functionality.

#The Menu System

Menus are a central feature of Sxmo and are navigable through using the Pinephone's 3 hardware buttons. Also you can use the touchscreen to tap your selection if you'd like as well. The menus are essentially scripts around a custom patched version of dmenu. Note that while using a menu, dwm's button bindings won't be triggered as these grab's are setup to be mutually exclusive from X's point of view.

The default menu bindings for the Pinephone buttons are:

  • Volume Raise: Previous item
  • Volume Lower: Next item
  • Power: Select item

#Included Menus

1. Application-specific context menus

The application-specific context menu (triggered by single tapping the volume raise key) lets you you access application-specific features of the currently focused window. For example while using mpv, the application-specific context menu lets you pause the video, increase/decrease volume, seek, etc. You can reference the sxmo_appmenu.sh script for a full list of functionality.

2. Global system menu (Sys)

The global system menu (triggered by double tapping the volume raise button) lets you launch applications, toggle system preferences and more. This is probably the closest thing to 'homescreen' in traditional phone OS's in that it can be the starting point to access much of the functionality in Sxmo. This menu lets you:

3. Global config menu (Config)

The global config menu is accessible by launching the global system menu aforementioned and selecting Config. This menu let you:

  • Adjust system brightness
  • Toggle modem monitoring, view modem information and the modem log
  • Rotate the screen rotation
  • Upgrade packages
  • Edit your configuration (your custom xinit)


DWM is a dynamic window manager with a master-slave stack layout. As such, the window manager automatically decides where windows should be placed. The algorithm used to decide where windows should be placed is governed by the icon to the right of the 4th workspace icon. Open some windows and you should get an understanding of the various layouts. By default, the layout is set the vertical stack layout and tapping icon representing the current layout will cycle through the available layouts.

When the monocle layout is active, it will only show one window that takes up the entire workspace. By tapping the left and right hand side of the title bar, you can cycle back and forth between the windows that are open.

For more info on DWM and other layouts that you can patch in, see the upstream website for dwm.


If you are in a call, the length of the call will be display adjacent to the title bar.

#Screen Lock

A (sxmo_screenlock) script enables you to lock the screen so no tap events are processed, to turn the screen off and preserve battery, and to enter suspend (deep sleep / CRUST). You can activate the screen lock by tapping the volume raise button three times quickly or holding it pressed for about three seconds. You will see the Pinephone's blue LED indicator activate.

The Screenlock has the aforemention three modes, each reflected by a specific LED colour:

  • Screenlock display on mode: Locks the screen and disables input; but keeps the screen on
    • Indicated by blue LED
  • Screenlock display off mode: Locks the screen, disables input, and turns the screen off
    • Indicated by purple LED
  • Screenlock deep sleep mode: Enters CRUST suspend / deep sleep
    • Indicated by red LED

Note that if you receive notifications in any of these states, the green LED will be enabled, turning the colour of the three states to respectively cyan, white or yellow.

While using the Screenlock, only the following bindings apply (and override the default dwm button bindings):

  • Volume Up Button:
    • 3 taps or long press: Enter screenlock deep sleep mode
  • Volume Down Button:
    • 3 taps or long press: Toggle between screenlock display on/off mode (however nops/ feature disabled if SXMO_LOCK_SCREEN_OFF=1)
  • Power button:
    • 3 taps or long press: Exit screen lock

When you are in deep sleep mode (entered by tapping volume raise 3 times), you can exit this mode and restore the above bindings by clicking the powerkey once. After exiting deep sleeep mode, within 5 seconds you should either press the volume lower or powerkey 3 times to switch modes or exit. After 5 seconds, the blinking stops and you will be kicked back into deep sleep mode. The purpose of this 5 second timeout is so that if you accidently press the powerkey when the phone is in your pocket, you won't inadvertently be kicked out of CRUST.

Sxmo ensures that cron jobs works, and will actively wake the phone from sleep temporarily to this end. The cron daemon is installed but not enabled in postmarketOS, so it has to be started manually (rc-service crond start) and set to start on boot (rc-update add crond default). We use a little program called mnc to wake the phone up before the next planned cron job. We also wrap some sxmo logic in a dedicated script called sxmo_rtcwake.sh which:

  • makes the led blink red/purple while doing the task
  • manages the screenlock state while doing the task
  • puts the phone back to crust when done
*/15 * * * * sxmo_rtcwake.sh sleep 10 2>> ~/.cache/sxmo/logs/dwm.log

This example will perform a quick wakeup every 15 minutes. You may want to redirect the standard error output to the main log as shown in the example above. You can pass the --strict parameter to sxmo_rtcwake.sh to only run when the phone is indeed in crust mode, otherwise it will run regardless of the lock state.

If you omit sxmo_rtcwake.sh for a job, the system will wake up and not go back to crust.

#Calls and Texting

Calling and texting is fully functional and should work out-of-the-box. Make sure you have the modem killswitch in the enabled position and wait a little bit after booting before trying modem functionality to allow the modem to connect.

Modem functionality is based on using the dmenu menu system and accessible through the global system menu. You'll need to explicitly toggle the modem there to receive calls/texts. If your SIM is locked, you must unlock it manually. The scripting behind the scenes works via ModemManager using the mmcli command line tool.

Unlocking SIM

SXMO ask for your SIM's PIN code using dmenu (since sxmo 1.4.1).

Alternatively, you can do so from the command-line as follows:

mmcli -i 0 --pin 1234

You could put this in your unlock sim hook (~/.config/sxmo/hooks/unlocksim), but there is of course a significant security risk involved if your device gets compromised!


To place a new call, you can use the Dialer entry in the global system menu. You will be prompted for a number to dial. Once the call connects, a menu will automatically be launched which let's you:

  • Manage audio routing
  • Send DTMF (dial) tones
  • Hang up the call
  • Lock the screen (via screen lock)


To view existing text message threads you can use the Texts entry in the global system menu. This menu will let you tail follow a logfile for your conversation with each number. When a new text is sent or received; the tail will automatically be updated with the new text contents.

While displaying the conversation you can pop out a contextual menu with power up button to reply by text or to start a call with the number.

You can also compose a new text message, from the Texts entry you will see a Send a Text entry which first prompt you for a number. After entering the destination number you will by default be dropped into a vim-like editor (vis) to compose your message. Once your message is as you'd like it, exit the editor using ZZ/:w/or by holding down (or triple clicking) the volume down key. You will now be taken to a new menu to confirm your message from which you can edit/send/cancel the message.

Monitoring for Incoming Calls/Texts

A vital feature of a working phone is being able to receive new texts and pickup calls. This functionality is made possible through a script that monitors the modem activities and vibrates the phone and blinks the green LED when there is an incoming text/call. This functionality is optional and can be toggled on/off (e.g. to have a 'silent' mode) via the Config menu. You can tell if modem monitoring is on with the dedicated icon that appears in dwm's bar.

While a call is incoming:

  • The vibration motor will trigger for 3 seconds
  • The green LED will trigger
  • A dmenu will appear to allow you to pickup the call. You can also discard the call or mute the ring. If you missed the menu, you can also open either the global or application menu and you'll see a menu entry to pickup the call; of course this is time-sensitive and this menu entry will only be visible while the other party's line is ringing

When a new text message comes in:

  • The vibration motor will trigger rapidly in 3 intervals for 300ms
  • The green LED will trigger If you are in a locked/suspended state the LED may turn cyan, white, yellow
  • To view the new text message, refer to the Texting section above

Contacts System

The Sxmo contacts system based on a plain TSV file that can be placed at $XDG_CONFIG_HOME/sxmo/contacts.tsv. This TSV file is expected to have two columns: phonenumber, and contactname. Upon receiving a call if you have a contact stored associated with the incoming number, the contact name will appear instead of the number. Also contact names will appear in the Texts and Dialer menus if they are present in the contacts TSV file. If no contacts.tsv is present, or the number is missing from this file; the contact in menus will show up as Unknown Number. An contacts.tsv example might look like:

+122345628	John Smith
+128371642	Jeff Foo
+31612345678	Jan Janssen

Dedicated Menu

There is a script named "Contacts" accessible from the main menu to manage those contacts. You can add, edit and delete all of your contacts.

International Numbers

Note that you should always prefix numbers you call out with, text to, or add to the contact system with their international prefix code and with the initial plus sign. The contact app menu will softly force you to specify your contacts with the leading country code. Note that you can still specify an "invalid" phone number (by example 123 or 888 or whatever your provider use).

Behind the scenes of mmcli, numbers sometimes come into the system with international prefixes and sometimes without. We think that this issue only happens with local phone numbers from the country your provider is in. So if you recieve a call from the number 54321 for example; it could come into mmcli as +154321 or as 54321 if this was a US number. To manage this, we use an environment variable named DEFAULT_COUNTRY to indicate which country your provider is. By example, if you are in France, you should configure this in your xinit export DEFAULT_COUNTRY=FR. Then Sxmo will handle any non-prefixed incoming phone number as a French one and add the +33 prefix automatically. You then can be assured that texts / outgoing / incoming calls will line up in regards to deduplication of contacts in menus and text message threads will stay intact.

#Included Scripts and Applications

In the global system menu there are entries for both applications and scripts.

Included Scripts:

  • Web Search: Search duckduckgo with the query provided by the user (bangs work too)
  • Files: A filebrowser that can handle opening audio and text files
  • Timer: A simple countdown timer script that vibrates the phones upon completion
  • Youtube: Search youtube by keyword in dmenu and then view in mpv (script based on idiotbox)
  • Youtube (audio): Search youtube by keyword in dmenu and then listen in mpv (script based on idiotbox)
  • Weather: United States weather forecast (by zipcode) dmenu script
  • RSS: Aggregates RSS feeds and let's you view by timespan dmenu script (based on sfeed)

Included Applications:

  • Surf: The suckless minimalistic browser based on Webkit
  • Netsurf: An alternative minimalistic browser that renders really fast
  • Firefox: The infamous FOSS browser often symbolized by a fox
  • Sacc: A great minimalistic gopher browser; launches by default to a good phlog aggregator
  • W3m: A text-based browser with vim-like keybindings
  • Xcalc: A nice (and fast) calculator app
  • St: The suckless terminal


At the time being the primary way to get connected to the Internet in Sxmo is through wifi. There is a menu entry in the global system menu to connect to wifi. This is essentially this is just a wrapper to launch nmtui. Make sure the killswitch for Wifi on your Pinephone is in the enabled position.

Mobile data should be manually for now (there is no built in menu to do this); so refer to postmarketOS pinephone documentation for that aspect.

#Audio Routing

You can use the Audio entry in the global system menu to toggle which audio output you want to send sound to.

Note that when in a call, the audio device selected in the global system menu won't automatically apply; rather audio will automatically be initially routed to the earpiece and then changeable through the in call menu. Upon the call ending, audio is always routed back to the headphone jack.

#Updating and Changelog

Sxmo's packages are currently distributed through packages in pmOS so when new package versions are periodically pushed; your install can be

To update run:

apk update
apk upgrade -a

There is also a menu entry within the Config menu to update as well which runs the same commands as above.

For details on what changed between package versions or image releases refer to the changelog.

#User Customizable Functionality

#Files and Folders

Filepath Description
$XDG_CONFIG_HOME/sxmo/xinit Automatically executed script executed upon starting X.

TSV file wherein each row is: contactnumber TAB contactname

If unset all contacts will show up as 'Unknown Number'

All phone numbers must be full phone numbers startings with + and the country code

$XDG_CONFIG_HOME/sxmo/sfeedrc Sfeedrc file (see sfeed documentation used by RSS script)
$XDG_CONFIG_HOME/sxmo/userscripts Directory or file to place user scripts which will automatically appear in the menu system
$XDG_CONFIG_HOME/sxmo/hooks/ring [^1]

Executable script to run when the phone is receiving a call / rings

This script is called with "$1" set to the incoming number and contact name.

$XDG_CONFIG_HOME/sxmo/hooks/pickup [^1]

Executable script to run when the phone is accepting an incoming call

$XDG_CONFIG_HOME/sxmo/hooks/missed_call [^1]

Executable script to run when the phone missed an incoming call

$XDG_CONFIG_HOME/sxmo/hooks/sms [^1]

Executable script to run when the phone is receiving a text

This script is called with "$1" set to the incoming number and contact name.

$XDG_CONFIG_HOME/sxmo/hooks/apps Executable script to run when display of the app menu is requested, outputs to stdout and allows you to override the default app menu (see sxmo_appmenu.sh)
$XDG_CONFIG_HOME/sxmo/hooks/scripts Executable script to run when display of the scripts menu is requested, outputs to stdout and allows you to override the default app menu (see sxmo_appmenu.sh)
$XDG_CONFIG_HOME/sxmo/hooks/presuspend [^1] Executable script that is executed prior to suspending the device. If the exit code of this script is non-zero, suspend will be cancelled
$XDG_CONFIG_HOME/sxmo/hooks/postwake [^1] Executable script that is executed after waking from suspension.
$XDG_CONFIG_HOME/sxmo/hooks/rtcwake Executable script that is executed every time the device temporarily wakes. You can use this script to check notifications from whatever back-end you desire. The temporary wake interval (in seconds )can be configured using the environment variable $SXMO_RTCWAKEINTERVAL . If this script exits with a non-zero exit code, suspension will be cancelled.
$XDG_CONFIG_HOME/sxmo/hooks/lock [^1] Executable script that is executed prior to locking the device
$XDG_CONFIG_HOME/sxmo/hooks/unlock [^1] Executable script that is executed immediately after unlocking the device
$XDG_CONFIG_HOME/sxmo/hooks/lisgdstart [^1] Script that is executed to start the gesture deamon, overrides the defaults (see ``sxmo_lisgdstart.sh``). This allows defining custom gestures.
$XDG_CONFIG_HOME/sxmo/hooks/inputhandler [^1] Script that is executed when a gesture is to be interpreted. It is passed the WM_CLASS of the active window as first parameter and the identifier/name of the gesture (or command to run) in the second argument, as configured with lisgd. See ``sxmo_inputhandler.sh`` for details. This script allows you to define your own context-sensitive (i.e. application specific) gestures.
$XDG_CONFIG_HOME/sxmo/hooks/audiostart [^1] This script is run by the default sway or xinit startup script to "Force audio over the main speaker and and set a sane default volume".
$XDG_CONFIG_HOME/sxmo/hooks/discard [^1] This script is executed (asynchronously) when you discard an incoming call
$XDG_CONFIG_HOME/sxmo/hooks/mute_ring [^1] This script is executed (asynchronously) when you mute an incoming call
$XDG_CONFIG_HOME/sxmo/hooks/notification [^1] This script will run whenever any kind of notification is received. It can be used for example to blink the led if you want to override the default behaviour
$XDG_CONFIG_HOME/sxmo/hooks/unlocksim [^1] This hook will run when your SIM needs to be unlocked with a PIN code. You can consider putting something like ``mmcli -i 0 --pin 1234`` in it to unlock automatically, if you don't mind the negative security implications that carries in case your device gets compromised.

Note: $XDG_CONFIG_HOME by default is equal to ~/.config

[^1]: If a user-defined hook file does not exist on activity, sxmo will run the corresponding project defined default hook from /usr/share/sxmo/default_hooks/. For example, if you pickup a call and $XDG_CONFIG_HOME/sxmo/hooks/pickup does not exist, /usr/share/sxmo/default_hooks/pickup will be run.



dwm log contains the standard error output of everything launched from your dwm session, so any scripts launched by sxmo will also log their output to this file.

dwm.log is helpful for debugging if your hooks are not working


contains standard error output from xinit

$XDG_CACHE_HOME/sxmo/youtubehistory.tsv This log file will save all the terms you've searched for using the youtube script.

Note: $XDG_CACHE_HOME by default is equal to ~/.cache

#Environment Variables

The following environment variables can be set:

Environment variable Description
$TERM Terminal to launch on double-clicking power button and used in scripts. Defaults to `st`.
$BROWSER Browser to launch on triple-clicking/holding power-button and used in scripts. Defaults to `surf`.
$KEYBOARD Keyboard to launch on single-clicking power button and used in scripts. Defaults to `svkbd-mobile-intl` or `svkbd-sxmo`
$EDITOR Editor to use to handle files (partial support; full support plans for composing texts etc). Defaults to `vis`.
$SXMO_RECDIR Directory that the Record script will save recordings to.
$SXMO_SUBREDDITS Subreddits (comma-separated) to appear in menu for Reddit script.

Files of GPS coordinates to populate the locations menu in the foxtrotgps menu.

Each file is expected to be a tsv; the first entry being the location; the second being lat, lon pair.

$SXMO_LOCK_SCREEN_OFF Boolean, set to 1 to immediately turn the screen off upon locking (this skips the default first stage)
$SXMO_LOCK_SUSPEND Boolean, set to 1 to immediately suspend the device upon locking (this skips the default first two stages)
$SXMO_NO_ICONS Boolean, set to 1 if you don't want any icons shown in the menus
$SVKBD_ENABLEOVERLAYS Boolean, set to 0 to disable the overlay functionality on the virtual keyboard (svkbd) (enabled by default), the overlay functionality is responsible for showing input variations such as diacritics when holding a key with a long press.
$SVKBD_LAYERS Comma separated list of layers to enable on the virtual keyboard. See the svkbd source for your layout for a definition of available layers.
$SVKBD_HEIGHTFACTOR Integer value expressing a height fraction, a one key row of the virtual keyboard takes 1/x of the screen height.
$DMENU_WRAP_AROUND Boolean value specifying whether dmenu interfaces should wrap around to the top/bottom of the list while scrolling. Set to `true` to enable (disabled by default).
$LISGD_THRESHOLD Integer expressing the distance a gesture much minimally have to be recognized (unit corresponds to pixels usually)
$LISGD_THRESHOLD_PRESSED Integer expressing the distance a gesture much minimally have to be recognized for gestures that act when pressed (such as volume/brightness control and scrolling) (unit corresponds to pixels usually)
$SXMO_THRESHOLD Integer expressing the time in milisecond between two input button press to consider them as one action row
$DEFAULT_COUNTRY String to indicate the default country sxmo should fallback to when the phone numbers are not country code prefixed. Should be set to a country code (iso-3166?) such as ``FR`` for France, ``DE`` for Germany, ``US`` for the Unites States.

#User-customizable xinitrc

For setting the above Environment Variables and also to launch custom programs upon starting X you can use the user customizable xinit described in the Files and Folders section. You will automatically be provided with a custom xinit based on the following template:

#!/usr/bin/env sh

# Please modify this file to your liking

# Important Instructions:
#  All processes you launch from this script must
#  be non-blocking: launch them in the background (using &)
#  or ensure they return quickly. Only after this script
#  finishes will the window manager be loaded

# Set a pretty wallpaper
feh --bg-fill /usr/share/sxmo/background.jpg

# Show conky (the clock)
conky -c /usr/share/sxmo/appcfg/conky.conf -d #12 hour clock (am/pm)
#conky -c /usr/share/sxmo/appcfg/conky24h.conf -d  #24 hour clock

# Force audio over the main speaker
# and set a sane default volume
sxmo_audioout.sh Speaker
amixer sset 'Line Out Source' 'Mono Differential','Mono Differential'
amixer set "Line Out" 50%

# Play a funky startup tune
#mpv --quiet --no-video /usr/share/sxmo/startup.ogg &

#  the sleep is there because the modem
#  might take a bit to be available
#  after first boot.
#sleep 20 && mmcli -i 0 --pin 1234

# turn on modemmonitor on login
# Note: if the modemmonitor is not on you can
# not receive texts/calls!
#sleep 22 && sxmo_modemmonitortoggle.sh on &

### Configuration Parameters ###

# Note that this is just a subset of all available
# parameters, see the sxmo documentation for more.

# Use firefox as default browser if installed
command -v firefox && export BROWSER=firefox

# Prepopulate Subreddits menu with custom subreddits
#export SXMO_SUBREDDITS="postmarketos pinephoneOfficial pinephone unixporn"

# Temporarily wake every 5 minutes during sleep
#(useful for getting notifications)

# Immediately turn the screen off when locking the device

# Immediately suspend the phone when locking

# When scrolling past the beginning or end of a menu, wrap it around:

# Enable audio feedback on keypress
#export KEYBOARD_ARGS="-o | clickclack -f /usr/share/sxmo/keypress.wav"

# Or, enable vibration feedback on keypress
#export KEYBOARD_ARGS="-o | clickclack -V"

Place the contents above into ~/.config/sxmo/xinit and restart X and customize away. Make sure that everything you launch from your custom xinitrc is either quick to run or launched in the background, otherwise your window manager (dwm) won't be loaded.

A good alternative place to put environment variables is in your ~/.profile, the advantage there is that it will also be available if you ssh into your phone.

#X resources

Certain interface parameters, such as the font size for dmenu, can be configured through X resources. Create a file ~/.Xresources and you have the following notable settings to tweak:


Set to the font and fontsize you want for all menus (dmenu). Defaults to Terminus-30.

#User Scripts

User scripts are custom scripts the user can run via the global system menu. To add your own custom userscript:

  • either create the $XDG_CONFIG_HOME/sxmo/userscripts directory and place your .sh scripts in the userscripts directory. Note, Userscripts should be set to be executable.
  • or touch the $XDG_CONFIG_HOME/sxmo/userscripts file and write your entries in it, following the appmenu format <name> ^ <should-return-to-menu> ^ <script-path-or-command> one entry per line. Example:  Weather ^ 0 ^ sxmo_terminal.sh -f "monospace:size=5" sh -c "curl http://wttr.in/ | less -SR"

For examples of scripts Sxmo users have made for their mobile devices, see:

#Further Customization

Much of Sxmo's core-functionality in regards to menus are built out via plain shell scripts. So further cutomization should be simple. See sxmo-util's scripts directory to get a better sense of how things are put together. You can edit the scripts on your system for temporary fixes and please consider contributing your changes if you believe your modifications may be useful to other users.


The sxmo_files.sh script (accessible via sxmo_appmenu.sh) follows the XDG MIME Applications standard. We have our own custom xdg-open implementation called sxmo_open.sh that will parse the mimeapps.list files and open the default application as set by the user. To change a default application review the format of the mimeapps.list and edit ~/.config/mimeapps.list.


Our login manager - XDM's background can be set by changing the file located at /usr/lib/X11/xdm/wallpaper.jpg to your desired background.

Further customization can be done by the user by cloning ~mil/sxmo-xdm-config, editing the files, and running make.


SXMO just provides you with a simple graphical environment on top of your favourite distribution, which by default is postmarketOS for SXMO. PostmarketOS is in turn based on Alpine Linux. You can install any packages your distribution provides from the command line as follows:

$ apk update
$ apk add name-of-the-package

The built-in application menu of sxmo is only aware of a subset of applications, and will only show them when installed, feel free to add more tools to the menus and submit a patch.

Update migrations

While developing Sxmo, we will eventually update the xinit template, or environment variable names, or update hooks or whatever. We use a script named sxmo_migrate.sh that try to simplify migrations. This script will first show the differences between configurations can also override them completely.